diff --git a/topics/openapi-spec-generation.md b/topics/openapi-spec-generation.md index 58766b015..99633e7e3 100644 --- a/topics/openapi-spec-generation.md +++ b/topics/openapi-spec-generation.md @@ -247,6 +247,61 @@ 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 [`@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") +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