Ktor extension which generates OpenAPI document.
Maven dependency:
<dependency>
<groupId>io.github.imashtak</groupId>
<artifactId>ktordoc-openapi</artifactId>
<version>0.3.0</version>
</dependency>
Gradle dependency:
implementation("io.github.imashtak:ktordoc-openapi:0.3.0")
Use generateOpenAPI
function to declare high level settings for OpenAPI document:
fun Application.configureOpenAPI() {
routing {
generateOpenAPI() {
info {
title("Example API")
version("1.0.0")
}
server {
url("http://127.0.0.1:8080")
}
}
}
}
Then wrap endpoints with api
function like this:
fun Application.configureRouting() {
routing {
api({
summary("hello world")
response("200") {
mediaType("application/json") {
schema(String::class)
}
}
}) {
get("/") {
call.respondText("\"Hello World!\"")
}
}
}
}
Note: generateOpenAPI
call MUST be placed after all routes definitions. Considering our example, Application
module may be declared like this:
fun Application.module() {
configureRouting()
configureOpenAPI()
}
So now, on app starting, the file openapi/documentation.yaml
will be created with complete OpenAPI spec of defined routes. Note that routes which are not wrapped with api
function will not be shown in spec.
It is easy to integrate with SwaggerUI or OpenAPI plugins:
fun Application.configureOpenAPI() {
routing {
generateOpenAPI(swaggerFile = "openapi.yaml") {}
swaggerUI(swaggerFile = "openapi.yaml")
}
}
There is a simple rule - api
function must wrap "leaf node" of routes "tree". In other words you have to place api
in the following manner:
fun Application.configureRouting() {
routing {
route("/v1") {
api({}) {
get("/") {
call.respondText("Hello World!")
}
}
}
}
}
Consider the following code:
fun Application.configureRouting() {
routing {
api({}) {
get("/some/{id}") {
call.respondText("Hello World!")
}
}
}
}
Parameter id
will automatically be added to OpenAPI specification as path parameter. Note that from OpenAPI point of view path parameters may be only required, but ktor can work with optional path parameters using syntax /some/{id?}
. If made so, generated OpenAPI will show id
parameter as required and there is nothing to do with that.
It is possible to add some docs to parameter:
fun Application.configureRouting() {
routing {
api({
parameter {
name("id")
description("description of `id` parameter")
}
}) {
get("/some/{id}") {
call.respondText("Hello World!")
}
}
}
}
Other fields such as in
, required
and schema
will be set automatically (if not set manually).
The same works for query parameters. Example uses Resources plugin:
@Resource("/some")
class Some(val label: String?)
fun Application.configureRouting() {
routing {
api({
parameter {
name("label")
description("description of `label` parameter")
}
}) {
get<Some> {
call.respondText("Hello World!")
}
}
}
}