Adding information about request and response bodies. ```kotlin get("hello", { request { body() { // request body } } response { HttpStatusCode.OK to { body() { // response body } } } }) { // handle request... } ``` ## Basic Body-Specification ```kotlin body() { description = "A brief description of the request body" required = true example("First", /*value*/) { summary = "A short summary of the example" description = "A longer description of the example" } example("Second", /*value*/) mediaType(ContentType.Application.Json) } body { // body without a schema //... } ``` - `description` - A brief description of the body - `required` - whether the body is required or optional - `example` - specifies a single example for the body. Any amount of examples can be added to a body. See below for more information. - `mediaType` - the media-type of the object (application/json or text/plain by default) ## Schema of the Body Any primitive or more complex Kotlin-class can be used as the schema of a body. If no media-type is specified, a matching one will be picket automatically. The media type for primitive types is currently always `text/plain` and `application/json` for complex types. ```kotlin body() body() body>() data class Pet( val id: Int, val name: String, val tag: String ) ``` Types can alternatively also be provided as a normal function-parameter, tough this method has some limitations, especially when it comes to generic-types. ```kotlin body(Int::class) body(Pet::class) body(Array::class) ``` ## Swagger @Schema-Annotation Classes and fields can be annotated with the `@Schema` and `@ArraySchema` annotations to add information such as an description, example-values, a title for the schema or whether a field is nullable. The tested and fully supported features of the `@Schema`-annotation are: `title`, `description`, `nullable`, `format`, `example`, `minLength`, `maxLength`, `minimum`, `maximum`, `minItems`, `maxItems`, `uniqueItems`. Example: ```kotlin @Schema(title = "The Schema for a person") data class Person( @field:Schema(description = "the name of the person", required = true) val name: String, @field:Schema(description = "the age of the person in years", nullable = true) val age: Int? ) ``` For more information, see /~https://github.com/victools/jsonschema-generator/tree/main/jsonschema-module-swagger-2 or /~https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Annotations#schema ## Multipart-Bodies The definition for multipart-bodies is similar to that of normal bodies. ```kotlin multipartBody { description = "A brief description of the request body" required = true mediaType(ContentType.MultiPart.FormData) part("myImage") { mediaTypes = setOf( ContentType.Image.PNG, ContentType.Image.JPEG, ContentType.Image.GIF ) } part("myMetadata") } //... data class Metadata( val format: String, val location: Coords ) data class Coords( val lat: Float, val long: Float ) ``` - `description` - A brief description of the body - `required` - whether the body is required or optional - `mediaType` - the media-type of the object (multipart/formdata by default) - `part` - one part of the body with the given name and type/schema (use `java.io.File` for file-uploads/downloads) - `mediaTypes` - specify custom valid content-types for the part - `headers` - include custom headers for the part ## Custom Schemas ### Custom Predefined Schemas Schemas can be pre-configured in the plugin-configuration and then referenced by an id. #### Configuration ```kotlin install(SwaggerUI) { schemas { json("myCustomJsonSchema") { """ { "type": "object", "properties": { ... } } """.trimIndent() } openApi("myCustomSchema") { Schema().apply { /*...*/ } } remote("myRemoteSchema", "http://localhost:8080/schemas/myschema.json") } } //... body(obj("myCustomJsonSchema")) body(obj("myCustomSchema")) body(obj("myRemoteSchema")) multipartBody { part("myPart", obj("myCustomSchema")) } ``` - **json** - provide the schema as a json-schema - **openApi** - provide the schema as a "Schema"-Object - **remote** - the schema can be found at the given url. Only the reference is added to the OpenApi-Spec, not the complete schema. #### Usage Custom schemas can be referenced by their id as the body of an request or response. ```kotlin body("myCustomJsonSchema") // "myCustomJsonSchema" is the schema of the body body(obj("myRemoteSchema")) // same as "body("myRemoteSchema")" body(array("myCustomSchema")) // body is an array with elements of in the schema "myCustomSchema" multipartBody { part("myPart", obj("myCustomSchema")) // same as part("myPart", "myCustomSchema") } ``` ### Custom Schema-Builder A custom builder for converting a `Type` to a json-schema can also be provided. ```kotlin install(SwaggerUI) { schemas { jsonSchemaBuilder { type -> myJsonSchemaBuilder(type) } } } ``` If `null` is returned for a type, the default built-in json-schema-builder is used for this type instead. ## Media Types A request/response body can have any amount of supported media types. If no media type is specified and a schema exists, a media type will automatically be chosen (usually "application/json" for complex models and arrays and "text/plain" for everything else) ```kotlin body() { mediaType(ContentType.Application.Json) mediaType(ContentType.Application.Xml) } body { mediaType(ContentType.Image.PNG) mediaType(ContentType.Image.JPEG) mediaType(ContentType.Image.SVG) } ``` ## Body Examples Example objects can be provided with each body. ```kotlin body() { example("First", Pet(1, "Chloe", "cat")) { summary = "A short summary of the example" description = "A longer description of the example" } example("Second", Pet(2, "Oliver", "dog")) } body>() { example("Example", listOf( Pet(1, "Chloe", "cat"), Pet(2, "Oliver", "dog") )) } data class Pet( val id: Int, val name: String, val tag: String ) ``` ```kotlin example(name: String, value: Any) { ... } ``` - `name` - each example must have a new - `value` - the example value as a kotlin/java object - `summary` - A short summary of the example - `description` - A longer description of the example Examples can also be auto-generated via the help of the annotations `@Example` or `@Schema`. Both can be added to fields of the models and no additional example has to be specified. Examples specifically provided with each route have higher priority than examples generated from annotations. Example using the `@Example`-Annotations: ```kotlin import io.github.smiley4.ktorswaggerui.dsl.Example data class Person( @Example("Steve") val name: String, @Example("42") val age: Int, @Example("172") val size: Float, @Example("false") val robot: Boolean, ) ``` Example using the `@Schema`-Annotation: ```kotlin import io.swagger.v3.oas.annotations.media.Schema data class Person( @field:Schema(example = "Steve") val name: String, @field:Schema(example = "42") val age: Int, @field:Schema(example = "172") val size: Float, @field:Schema(example = "false") val robot: Boolean ) ```