Giter VIP home page Giter VIP logo

restful-service's Introduction

restful-service

restful-service is your new project powered by Ktor framework.

Ktor

Company website: im.professional.com Ktor Version: 1.5.2 Kotlin Version: 1.4.10 BuildSystem: Gradle with Kotlin DSL

Ktor Documentation

Ktor is a framework for quickly creating web applications in Kotlin with minimal effort.

Selected Features:

Routing Documentation (JetBrains)

Allows to define structured routes and associated handlers.

Description

Routing is a feature that is installed into an Application to simplify and structure page request handling. This page explains the routing feature. Extracting information about a request, and generating valid responses inside a route, is described on the requests and responses pages.

    get("/") {
        call.respondText("Hello, World!")
    }
    get("/bye") {
        call.respondText("Good bye, World!")
    }

get, post, put, delete, head and options functions are convenience shortcuts to a flexible and powerful routing system. In particular, get is an alias to route(HttpMethod.Get, path) { handle(body) }, where body is a lambda passed to the get function.

Usage

Routing Tree

Routing is organized in a tree with a recursive matching system that is capable of handling quite complex rules for request processing. The Tree is built with nodes and selectors. The Node contains handlers and interceptors, and the selector is attached to an arc which connects another node. If selector matches current routing evaluation context, the algorithm goes down to the node associated with that selector.

Routing is built using a DSL in a nested manner:

route("a") { // matches first segment with the value "a"
  route("b") { // matches second segment with the value "b"
     get {…} // matches GET verb, and installs a handler
     post {…} // matches POST verb, and installs a handler
  }
}
method(HttpMethod.Get) { // matches GET verb
   route("a") { // matches first segment with the value "a"
      route("b") { // matches second segment with the value "b"
         handle { … } // installs handler
      }
   }
}
```kotlin
route resolution algorithms go through nodes recursively discarding subtrees where selector didn't match.

Builder functions:
* `route(path)` – adds path segments matcher(s), see below about paths
* `method(verb)` – adds HTTP method matcher.
* `param(name, value)` – adds matcher for a specific value of the query parameter
* `param(name)` – adds matcher that checks for the existence of a query parameter and captures its value
* `optionalParam(name)` – adds matcher that captures the value of a query parameter if it exists
* `header(name, value)` – adds matcher that for a specific value of HTTP header, see below about quality

## Path
Building routing tree by hand would be very inconvenient. Thus there is `route` function that covers most of the use cases in a simple way, using path.

`route` function (and respective HTTP verb aliases) receives a `path` as a parameter which is processed to build routing tree. First, it is split into path segments by the `/` delimiter. Each segment generates a nested routing node.

These two variants are equivalent:

```kotlin
route("/foo/bar") { … } // (1)

route("/foo") {
   route("bar") { … } // (2)
}

Parameters

Path can also contain parameters that match specific path segment and capture its value into parameters properties of an application call:

get("/user/{login}") {
   val login = call.parameters["login"]
}

When user agent requests /user/john using GET method, this route is matched and parameters property will have "login" key with value "john".

Optional, Wildcard, Tailcard

Parameters and path segments can be optional or capture entire remainder of URI.

  • {param?} –- optional path segment, if it exists it's captured in the parameter
  • * –- wildcard, any segment will match, but shouldn't be missing
  • {...} –- tailcard, matches all the rest of the URI, should be last. Can be empty.
  • {param...} –- captured tailcard, matches all the rest of the URI and puts multiple values for each path segment into parameters using param as key. Use call.parameters.getAll("param") to get all values.

Examples:

get("/user/{login}/{fullname?}") { … }
get("/resources/{path...}") { … }

Quality

It is not unlikely that several routes can match to the same HTTP request.

One example is matching on the Accept HTTP header which can have multiple values with specified priority (quality).

accept(ContentType.Text.Plain) { … }
accept(ContentType.Text.Html) { … }

The routing matching algorithm not only checks if a particular HTTP request matches a specific path in a routing tree, but it also calculates the quality of the match and selects the routing node with the best quality. Given the routes above, which match on the Accept header, and given the request header Accept: text/plain; q=0.5, text/html will match text/html because the quality factor in the HTTP header indicates a lower quality fortext/plain (default is 1.0) .

The Header Accept: text/plain, text/* will match text/plain. Wildcard matches are considered less specific than direct matches. Therefore the routing matching algorithm will consider them to have a lower quality.

Another example is making short URLs to named entities, e.g. users, and still being able to prefer specific pages like "settings". An example would be

  • https://twitter.com/kotlin -– displays user "kotlin"
  • https://twitter.com/settings -- displays settings page

This can be implemented like this:

get("/{user}") { … }
get("/settings") { … }

The parameter is considered to have a lower quality than a constant string, so that even if /settings matches both, the second route will be selected.

Options

No options()

ContentNegotiation Documentation (JetBrains)

Provides automatic content conversion according to Content-Type and Accept headers.

Description

The ContentNegotiation feature serves two primary purposes:

  • Negotiating media types between the client and server. For this, it uses the Accept and Content-Type headers.
  • Serializing/deserializing the content in the specific format, which is provided by either the built-in kotlinx.serialization library or external ones, such as Gson and Jackson, amongst others.

Usage

Installation

To install the ContentNegotiation feature, pass it to the install function in the application initialization code. This can be the main function ...

import io.ktor.features.*
// ...
fun Application.main() {
  install(ContentNegotiation)
  // ...
}

... or a specified module:

import io.ktor.features.*
// ...
fun Application.module() {
    install(ContentNegotiation)
    // ...
}

Register a Converter

To register a converter for a specified Content-Type, you need to call the register method. In the example below, two custom converters are registered to deserialize application/json and application/xml data:

install(ContentNegotiation) {
    register(ContentType.Application.Json, CustomJsonConverter())
    register(ContentType.Application.Xml, CustomXmlConverter())
}

Built-in Converters

Ktor provides the set of built-in converters for handing various content types without writing your own logic:

  • Gson for JSON

  • Jackson for JSON

  • kotlinx.serialization for JSON, Protobuf, CBOR, and so on

See a corresponding topic to learn how to install the required dependencies, register, and configure a converter.

Receive and Send Data

Create a Data Class

To deserialize received data into an object, you need to create a data class, for example:

data class Customer(val id: Int, val firstName: String, val lastName: String)

If you use kotlinx.serialization, make sure that this class has the @Serializable annotation:

import kotlinx.serialization.Serializable

@Serializable
data class Customer(val id: Int, val firstName: String, val lastName: String)

Receive Data

To receive and convert a content for a request, call the receive method that accepts a data class as a parameter:

post("/customer") {
    val customer = call.receive<Customer>()
}

The Content-Type of the request will be used to choose a converter for processing the request. The example below shows a sample HTTP client request containing JSON data that will be converted to a Customer object on the server side:

post http://0.0.0.0:8080/customer
Content-Type: application/json

{
  "id": 1,
  "firstName" : "Jet",
  "lastName": "Brains"
}

Send Data

To pass a data object in a response, you can use the respond method:

post("/customer") {
    call.respond(Customer(1, "Jet", "Brains"))
}

In this case, Ktor uses the Accept header to choose the required converter.

Implement a Custom Converter

In Ktor, you can write your own converter for serializing/deserializing data. To do this, you need to implement the ContentConverter interface:

interface ContentConverter {
    suspend fun convertForSend(context: PipelineContext<Any, ApplicationCall>, contentType: ContentType, value: Any): Any?
    suspend fun convertForReceive(context: PipelineContext<ApplicationReceiveRequest, ApplicationCall>): Any?
}

Take a look at the GsonConverter class as an implementation example.

Options

No options()

kotlinx.serialization Documentation (JetBrains)

Handles JSON serialization using kotlinx.serialization library

Description

ContentNegotiation allows you to use content converters provided by the kotlinx.serialization library. This library supports JSON, CBOR, ProtoBuf, and other formats.

Usage

Register the JSON Converter

To register the JSON converter in your application, call the json method:

import io.ktor.serialization.*

install(ContentNegotiation) {
    json()
}

Inside the json method, you can access the JsonBuilder API, for example:

install(ContentNegotiation) {
    json(Json {
        prettyPrint = true
        isLenient = true
        // ...
    })
}

Register an Arbitrary Converter

To register an arbitrary converter from the kotlinx.serialization library (such as Protobuf or CBOR), call the serialization method and pass two parameters:

  • The required ContentType value.
  • An object of the class implementing the required encoder/decoder.

For example, you can register the Cbor converter in the following way:

install(ContentNegotiation) {
    serialization(ContentType.Application.Cbor, Cbor.Default)
}

Options

No options()

Reporting Issues / Support

Please use our issue tracker for filing feature requests and bugs. If you'd like to ask a question, we recommmend StackOverflow where members of the team monitor frequently.

There is also community support on the Kotlin Slack Ktor channel

Reporting Security Vulnerabilities

If you find a security vulnerability in Ktor, we kindly request that you reach out to the JetBrains security team via our responsible disclosure process.

Contributing

Please see the contribution guide and the Code of conduct before contributing.

TODO: contribution of features guide (link)

restful-service's People

Contributors

bgubanov avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.