Skip to content

Multiple Specs

An example showing the setup with multiple OpenAPI specification in a single application.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package io.github.smiley4.ktoropenapi.examples

import io.github.smiley4.ktoropenapi.OpenApi
import io.github.smiley4.ktoropenapi.get
import io.github.smiley4.ktoropenapi.openApi
import io.github.smiley4.ktoropenapi.route
import io.github.smiley4.ktorredoc.redoc
import io.github.smiley4.ktorswaggerui.swaggerUI
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.response.respondText
import io.ktor.server.routing.route
import io.ktor.server.routing.routing

fun main() {
    embeddedServer(Netty, port = 8080, host = "localhost", module = Application::myModule).start(wait = true)
}

private fun Application.myModule() {

    // Install and configure the OpenAPI plugin
    install(OpenApi) {
        // "global" configuration for all specs
        info {
            title = "Example API"
        }
        // configuration specific for spec "version1", overwrites global config
        spec("version1") {
            info {
                version = "1.0"
            }
        }
        // configuration specific for spec "version2", overwrites global config
        spec("version2") {
            info {
                version = "2.0"
            }
        }
        // assign all unassigned routes to spec "version2" (here only route '/greet')
        specAssigner = { _, _ -> "version2" }
    }

    routing {

        // add routes for "version1" spec, Swagger UI and ReDoc
        route("v1") {
            // OpenAPI spec containing all routes assigned to "version1"
            route("api.json") {
                openApi("version1")
            }
            // Swagger UI using '/v1/api.json'
            route("swagger") {
                swaggerUI("/v1/api.json")
            }
            // ReDoc using '/v1/api.json'
            route("redoc") {
                redoc("/v1/api.json")
            }
        }

        // add routes for "version2" spec, Swagger UI and ReDoc
        route("v2") {
            // OpenAPI spec containing all routes assigned to "version2"
            route("api.json") {
                openApi("version2")
            }
            // Swagger UI using '/v2/api.json'
            route("swagger") {
                swaggerUI("/v2/api.json")
            }
            // ReDoc using '/v2/api.json'
            route("redoc") {
                redoc("/v2/api.json")
            }
        }

        // version 1.0 routes
        route("v1", {
            specName = "version1"
        }) {

            // "hello" route in version 1.0
            get("hello", {
                description = "Version 1 'Hello World'"
            }) {
                call.respondText("Hello World!")
            }

        }

        // version 2.0 routes
        route("v2", {
            specName = "version2"
        }) {

            // "hello" route in version 2.0
            get("hello", {
                description = "Version 2 'Hello World'"
            }) {
                call.respondText("Hello World! (improved)")
            }

        }

        // unassigned route
        get("greet", {
            description = "Alternative route not manually assigned to any spec."
        }) {
            call.respondText("Alternative Hello World!")
        }

    }

}