From f9f4c75d7276f27a0a25330e7ab60a115992b2a8 Mon Sep 17 00:00:00 2001 From: vnikolova Date: Wed, 21 Jan 2026 15:46:55 +0100 Subject: [PATCH 1/2] KTOR-9255 Docs for JSON schema inference --- topics/openapi-spec-generation.md | 54 +++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/topics/openapi-spec-generation.md b/topics/openapi-spec-generation.md index 58766b015..42d25bb58 100644 --- a/topics/openapi-spec-generation.md +++ b/topics/openapi-spec-generation.md @@ -247,6 +247,60 @@ to [generate the OpenAPI specification](#assemble-and-serve-the-specification) i The OpenAPI and Swagger UI plugins call `.hide()` automatically, so their routes are excluded from the resulting document. +## Schema inference + +Ktor automatically generates JSON schemas for request and response types when building OpenAPI specifications. By +default, schemas are inferred from type references using `kotlinx-serialization` descriptors on data classes. This +allows most common data models to be documented without extra effort. + +### Customize schemas with annotations + +You can override automatically generated JSON schema fields by adding annotations to your data classes: + +```kotlin +@JsonSchema.Description("Represents a news article") +data class Article( + val title: String, + val content: String +) +``` + +### Use reflection-based schema inference + +For projects using Jackson or Gson instead of `kotlinx-serialization`, you can use reflection-based schema +inference. To do that, set the `schemaInference` field in the `Routing` source on the OpenAPI or SwaggerUI plugins: + +```kotlin +openAPI("docs") { + outputPath = "docs/routes" + info = OpenApiInfo("Books API from routes", "1.0.0") + source = OpenApiDocSource.Routing( + contentType = ContentType.Application.Json, + schemaInference = ReflectionJsonSchemaInference.Default, + ) +} +``` + +### Customize reflection behavior + +You can provide a custom `SchemaReflectionAdapter` to handle annotations or naming conventions that are not directly +supported. + +`SchemaReflectionAdapter` is a field of `ReflectionJsonSchemaInference`, which allows you to override default behavior, +such as property names, ignored fields, or nullability rules. + +For example, you can customize the behavior to support Gson’s `@SerializedName` annotation: + +```kotlin +ReflectionJsonSchemaInference(object : SchemaReflectionAdapter { + override fun getName(type: KType): String? { + return (type.classifier as? KClass<*>)?.let { + findAnnotations(SerializedName::class)?.value ?: it.simpleName + } + } +}) +``` + ## Generate and serve the specification The OpenAPI specification is assembled at runtime from runtime route annotations and metadata generated by the compiler From dfdb4a939e4e795de68445c9bbbd37981030ced5 Mon Sep 17 00:00:00 2001 From: vnikolova Date: Tue, 10 Feb 2026 18:05:30 +0100 Subject: [PATCH 2/2] add an API link to JsonSchema and clarify text --- topics/openapi-spec-generation.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/topics/openapi-spec-generation.md b/topics/openapi-spec-generation.md index 42d25bb58..99633e7e3 100644 --- a/topics/openapi-spec-generation.md +++ b/topics/openapi-spec-generation.md @@ -255,7 +255,8 @@ allows most common data models to be documented without extra effort. ### Customize schemas with annotations -You can override automatically generated JSON schema fields by adding annotations to your data classes: +You can override automatically generated JSON schema fields by adding [`@JsonSchema`](https://api.ktor.io/ktor-openapi-schema/io.ktor.openapi/-json-schema/index.html) +annotations to your data classes. This allows you to add descriptions, mark fields as required, and more: ```kotlin @JsonSchema.Description("Represents a news article")