Skip to content

Commit

Permalink
example config
Browse files Browse the repository at this point in the history
  • Loading branch information
SMILEY4 committed May 8, 2024
1 parent 910fb98 commit b12e05d
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ private fun Application.myModule() {
call.respondText("Hello World!")
}




}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package io.github.smiley4.ktorswaggerui.examples

import io.github.smiley4.ktorswaggerui.SwaggerUI
import io.github.smiley4.ktorswaggerui.data.KTypeDescriptor
import io.github.smiley4.ktorswaggerui.data.RefExampleDescriptor
import io.github.smiley4.ktorswaggerui.data.ValueExampleDescriptor
import io.github.smiley4.ktorswaggerui.dsl.routing.get
import io.github.smiley4.ktorswaggerui.routing.openApiSpec
import io.github.smiley4.ktorswaggerui.routing.swaggerUI
import io.ktor.server.application.Application
import io.ktor.server.application.call
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
import kotlin.reflect.typeOf

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

private fun Application.myModule() {

// Install and customize the "SwaggerUI"-Plugin
install(SwaggerUI) {
examples {

// specify two shared examples
example(ValueExampleDescriptor(
name = "Shared A",
description = "first shared example",
value = MyExampleClass(
someValue = "shared a"
)
))
example(ValueExampleDescriptor(
name = "Shared B",
description = "second shared example",
value = MyExampleClass(
someValue = "shared b"
)
))

}
}

routing {

// add the routes for swagger-ui and api-spec
route("swagger") {
swaggerUI("/api.json")
}
route("api.json") {
openApiSpec()
}


get("basic", {
request {
body(KTypeDescriptor(typeOf<MyExampleClass>())) {
// specify two example values
example(
ValueExampleDescriptor(
name = "Example 1",
description = "A first example value",
value = MyExampleClass(
someValue = "example 1"
),
)
)
example(
ValueExampleDescriptor(
name = "Example 2",
description = "A second example value",
value = MyExampleClass(
someValue = "example 2"
),
)
)
}
}
}) {
call.respondText("...")
}


get("reference-shared", {
request {
body(KTypeDescriptor(typeOf<MyExampleClass>())) {
// reference two shared examples specified in the plugin-config (and placed in the component section)
example(
RefExampleDescriptor("Example 1", "Shared A")
)
example(
RefExampleDescriptor("Example 2", "Shared B")
)
}
}
}) {
call.respondText("...")
}

}

}


private data class MyExampleClass(
val someValue: String
)

Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private fun Application.myModule() {
}
}
examples {
example(ValueExampleDescriptor("Unexpected Error", ErrorModel("Unexpected Error"), null, null, null))
example(ValueExampleDescriptor("Unexpected Error", ErrorModel("Unexpected Error"), null, null))
}
schemas {
schema("Pet", KTypeDescriptor(typeOf<Pet>()))
Expand All @@ -72,12 +72,12 @@ private fun Application.myModule() {
queryParameter("tags", KTypeDescriptor(typeOf<List<String>>())) {
description = "tags to filter by"
required = false
example = ValueExampleDescriptor("dog", "default", null, null, null)
example = ValueExampleDescriptor("dog", "default", null, null)
}
queryParameter("limit", KTypeDescriptor(typeOf<Int>())) {
description = "maximum number of results to return"
required = false
example = ValueExampleDescriptor("default", 100, null, null, null)
example = ValueExampleDescriptor("default", 100, null, null)
}
}
response {
Expand All @@ -98,7 +98,7 @@ private fun Application.myModule() {
name = "Charlie",
tag = "dog"
)
), null, null, true
), null, null
)
)
}
Expand Down Expand Up @@ -127,7 +127,7 @@ private fun Application.myModule() {
NewPet(
name = "Big Bird",
tag = "bird"
), null, null, true
), null, null
)
)
example(
Expand All @@ -136,7 +136,7 @@ private fun Application.myModule() {
NewPet(
name = "Charlie",
tag = "dog"
), null, null, true
), null, null
)
)
}
Expand All @@ -152,7 +152,7 @@ private fun Application.myModule() {
id = 123,
name = "Big Bird",
tag = "bird"
), null, null, true
), null, null
)
)
example(
Expand All @@ -162,7 +162,7 @@ private fun Application.myModule() {
id = 456,
name = "Charlie",
tag = "dog"
), null, null, true
), null, null
)
)
}
Expand All @@ -187,7 +187,7 @@ private fun Application.myModule() {
pathParameter("id", KTypeDescriptor(typeOf<Long>())) {
description = "Id of pet to fetch"
required = true
example = ValueExampleDescriptor("default", 123L, null, null, null)
example = ValueExampleDescriptor("default", 123L, null, null)
}
}
response {
Expand All @@ -201,7 +201,7 @@ private fun Application.myModule() {
id = 123,
name = "Big Bird",
tag = "bird"
), null, null, true
), null, null
)
)
example(
Expand All @@ -211,7 +211,7 @@ private fun Application.myModule() {
id = 123,
name = "Charlie",
tag = "dog"
), null, null, true
), null, null
)
)
}
Expand All @@ -237,7 +237,7 @@ private fun Application.myModule() {
pathParameter("id", KTypeDescriptor(typeOf<Long>())) {
description = "Id of pet to delete"
required = true
example = ValueExampleDescriptor("default", 123L, null, null, true)
example = ValueExampleDescriptor("default", 123L, null, null)
}
}
response {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fun main() {

private fun Application.myModule() {

// Install the "SwaggerUI"-Plugin and use the default configuration
// Install and customize the "SwaggerUI"-Plugin
install(SwaggerUI) {
schemas {

Expand All @@ -48,7 +48,7 @@ private fun Application.myModule() {
))

// add a type to the component-section of the api-spec with the id "type-schema"
schema("type-schema", KTypeDescriptor(typeOf<MyClass>()))
schema("type-schema", KTypeDescriptor(typeOf<MySchemaClass>()))

// overwrite 'LocalDateTime' with custom schema (root only)
overwrite[typeOf<LocalDateTime>()] = SwaggerTypeDescriptor(
Expand All @@ -73,13 +73,26 @@ private fun Application.myModule() {
}

routing {

// add the routes for swagger-ui and api-spec
route("swagger") {
swaggerUI("/api.json")
}
route("api.json") {
openApiSpec()
}


get("basic", {
request {
// directly specify the schema type
body(KTypeDescriptor(typeOf<MySchemaClass>()))
}
}) {
call.respondText("...")
}


get("global-swagger-schema", {
request {
// reference and use the schema from the component-section with the id "swagger-schema"
Expand All @@ -89,6 +102,7 @@ private fun Application.myModule() {
call.respondText("...")
}


get("global-type-schema", {
request {
// reference and use the schema from the component-section with the id "type-schema"
Expand All @@ -98,6 +112,7 @@ private fun Application.myModule() {
call.respondText("...")
}


get("array-schema", {
request {
// an array of items with the referenced schema with the id "type-schema"
Expand All @@ -111,6 +126,7 @@ private fun Application.myModule() {
call.respondText("...")
}


get("anyof-schema", {
request {
// either the referenced schema with id "type-schema" or "swagger-schema"
Expand All @@ -127,6 +143,7 @@ private fun Application.myModule() {
call.respondText("...")
}


get("type-overwrite", {
request {
// schema is not generated the normal way but the overwriting schema from the config is used instead
Expand All @@ -136,6 +153,7 @@ private fun Application.myModule() {
call.respondText("...")
}


get("jackson-subtypes", {
request {
// jackson subtypes are detected automatically
Expand All @@ -150,7 +168,7 @@ private fun Application.myModule() {
}


private data class MyClass(
private data class MySchemaClass(
val someValue: String
)

Expand All @@ -159,6 +177,8 @@ private data class MyClass(
JsonSubTypes.Type(value = SubTypeA::class),
JsonSubTypes.Type(value = SubTypeB::class),
)
open class BaseType(val base: String)
class SubTypeA(base: String, val a: Int) : BaseType(base)
class SubTypeB(base: String, val b: Boolean) : BaseType(base)
private open class BaseType(val base: String)

private class SubTypeA(base: String, val a: Int) : BaseType(base)

private class SubTypeB(base: String, val b: Boolean) : BaseType(base)
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,15 @@ class ExampleContextImpl : ExampleContext {
private val componentExamples = mutableMapOf<String, Example>()

fun addGlobal(config: ExampleConfigData) {
config.examples.forEach { (_, exampleDescriptor) ->
config.sharedExamples.forEach { (_, exampleDescriptor) ->
val example = generateExample(exampleDescriptor)
componentExamples[exampleDescriptor.name] = example
}
}

fun add(routes: Collection<RouteMeta>) {
collectExampleDescriptors(routes).forEach { exampleDescriptor ->
val example = generateExample(exampleDescriptor)
if (exampleDescriptor is ValueExampleDescriptor && exampleDescriptor.inComponents == true) {
rootExamples[exampleDescriptor] = Example().also {
it.`$ref` = "#/components/examples/${exampleDescriptor.name}"
}
componentExamples[exampleDescriptor.name] = example
} else {
rootExamples[exampleDescriptor] = example
}
rootExamples[exampleDescriptor] = generateExample(exampleDescriptor)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.github.smiley4.ktorswaggerui.data

class ExampleConfigData(
val examples: Map<String, ExampleDescriptor>
val sharedExamples: Map<String, ExampleDescriptor>
) {

companion object {
val DEFAULT = ExampleConfigData(
examples = emptyMap()
sharedExamples = emptyMap()
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ sealed class ExampleDescriptor(
class ValueExampleDescriptor(
name: String,
val value: Any?,
val summary: String?,
val description: String?,
val inComponents: Boolean?,
val summary: String? = null,
val description: String? = null,
) : ExampleDescriptor(name)

class RefExampleDescriptor(name: String, val refName: String): ExampleDescriptor(name)
Expand Down
Loading

0 comments on commit b12e05d

Please sign in to comment.