Documenting Routes
The ktor-openapi
plugin provides functions to create documented get
, post
, put
, delete
, patch
, options
, head
, route
and method
routes.
These work exactly the same as their respective base Ktor functions, but allow OpenAPI documentation to be added.
Routes provided by the plugin and routes from Ktor can be mixed and allow for a gradual enhancement of the api with documentation.
Adding Documentation to Routes
import io.github.smiley4.ktoropenapi.get //(1)!
get("hello", {
description = "A Hello-World route" //(2)!
request { //(3)!
queryParameter<String>("name") { //(4)!
description = "the name to greet"
}
}
response { //(5)!
code(HttpStatusCode.OK) { //(6)!
description = "successful request"
}
}
}) {
call.respond(HttpStatusCode.NotImplemented, Unit) //(7)!
}
- Replace
io.ktor.server.routing.get
withio.github.smiley4.ktoropenapi.get
. Same for other http methods. - Add a description to the route.
- Document request information, e.g. parameters, headers, bodies, etc.
- Specify a query parameter
name
of typeString
and add a description. - Document possible responses, response bodies, headers, etc.
- Specify a possible response with the status code
200 OK
and add a description. - Handle requests as usual.
Nested Documentation
Documentation can be added at any level and documentation of parent and child routes are merged together, with priority given to the deepest route.
route("parent", {
description = "Common description for all routes." //(1)!
}) {
get("child1") { //(2)!
call.respond(HttpStatusCode.NotImplemented, Unit)
}
get("child2", {
description = "Specific description of child 2." //(3)!
}) {
call.respond(HttpStatusCode.NotImplemented, Unit)
}
}
- The route
/parent
has a description added to it. This description applies to this route and all child routes, as long as it is not overwritten by any deeper route. /parent/child1
does not have any own documentation and only the information of the parent routes applies./parent/child2
specifies its own description and overwrites the description of the parent route.
API Reference
API Reference for more information on available documentation options for routes.
Documenting Requests
Information about a request is added in the request
-block of a route-documentation.
Adding Information About a Request
post("entity/{id}", {
description = "Create a new entity."
request { //(1)!
pathParameter<String>("id") { //(2)!
description = "The id of the entity to create."
example("default") {
value = UUID.randomUUID().toString()
}
}
body<NewEntity> { //(3)!
description = "The data of the new entity to create."
required = true
example("default") {
value = NewEntity()
}
}
}
}) {
call.respond(HttpStatusCode.NotImplemented, Unit)
}
- Add all information about http requests in the
request
-block.. - Add documentation about the path parameter with the name
id
of typeString
. - Add documentation about the request body. The body must be present (
required = true
) and be of typeNewEntity
.
API Reference
API Reference for more information on available documentation options for requests.
Documenting Responses
Information about possible responses is added in the response
-block of a route-documentation.
Adding Information About Responses
get("entities", {
description = "Returns all entities from the system that the user has access to."
response {
code(HttpStatusCode.OK) { //(1)!
body<List<Entity>> { //(2)!
required = true
description = "The list of available entities."
}
}
code(HttpStatusCode.Unauthorized) {
description = "The user is not authorized to view the list of entities."
}
default { //(3)!
body<ErrorModel> {
description = "An unexpected error occurred"
}
}
}
}) {
call.respond(HttpStatusCode.NotImplemented, Unit)
}
- Add information for a response with a
200 OK
status code. - Specify the body of this response. The body must be present (
required = true
) and be of typeList<Entity>
. - Document the default response."
Alternative Syntax for Status Codes
There are two alternative ways of specifying response codes. Both are valid options and functionally the same.
response {
code(HttpStatusCode.OK) {
//...
}
}
response {
HttpStatusCode.OK to {
//...
}
}
API Reference
API Reference for more information on available documentation options for requests.
Documenting Webhooks
Even though Webhooks are not a part of a Ktor server application, they can be added to the OpenAPI specification for documentation purposes.
Documenting Webhooks
import io.github.smiley4.ktoropenapi.webhook
routing {
webhook(HttpMethod.Post, "alert") { //(1)!
description = "Notify the registered URL with details of an upcoming concert" //(2)!
request {
body<String> {
mediaTypes(ContentType.Text.Plain)
required = true
}
}
}
}
- Add the webhook using the route extension function. This does not create any callable Ktor route and is only for documentation purposes.
- Document the webhook route like any other route.
More Information
Documenting SSE-Routes
For discoverability purposes, server-sent event routes can be added to the OpenAPI specification. Ktor SSE routes do not have an own extension function allowing for api documentation to be added. Instead, they have to be wrapped in a parent route containing the desired documentation.
routing {
route({
description = "Send notifications to the client." //(1)!
}) {
sse("/events") { /*...*/ } //(2)!
}
}
- The parent route with the desired api documentation.
- The SSE route.
Warning
Support for server-sent events in OpenAPI and this plugin is limited. Even though all documentation options are technically available, not all may work or have the intended effect.