Type Overrides¶
Configure how specific types are represented in the generated OpenAPI schema.
Overview¶
Type overrides let you control how Kotlin/Java types are serialized in your OpenAPI specification. This is useful for:
- Date/Time types - Map
Instant,LocalDate, etc. to proper OpenAPI formats - Custom types - Define schemas for domain-specific types
- Third-party types - Handle types from libraries you don't control
- UUIDs and IDs - Ensure proper string formatting
Basic Usage¶
swagger {
documentation {
serialOverrides {
typeOverride("java.time.Instant") {
serializedAs = "string"
format = "date-time"
}
}
}
}
Common Overrides¶
Date and Time Types¶
serialOverrides {
// ISO 8601 date-time (2024-01-15T10:30:00Z)
typeOverride("java.time.Instant") {
serializedAs = "string"
format = "date-time"
}
// ISO 8601 date-time with timezone
typeOverride("java.time.ZonedDateTime") {
serializedAs = "string"
format = "date-time"
}
typeOverride("java.time.OffsetDateTime") {
serializedAs = "string"
format = "date-time"
}
// ISO 8601 date (2024-01-15)
typeOverride("java.time.LocalDate") {
serializedAs = "string"
format = "date"
}
// ISO 8601 time (10:30:00)
typeOverride("java.time.LocalTime") {
serializedAs = "string"
format = "time"
}
// Date-time without timezone
typeOverride("java.time.LocalDateTime") {
serializedAs = "string"
format = "date-time"
}
// Duration (PT1H30M)
typeOverride("java.time.Duration") {
serializedAs = "string"
format = "duration"
}
}
UUID¶
serialOverrides {
typeOverride("java.util.UUID") {
serializedAs = "string"
format = "uuid"
}
}
URI and URL¶
serialOverrides {
typeOverride("java.net.URI") {
serializedAs = "string"
format = "uri"
}
typeOverride("java.net.URL") {
serializedAs = "string"
format = "uri"
}
}
BigDecimal and BigInteger¶
serialOverrides {
typeOverride("java.math.BigDecimal") {
serializedAs = "string"
format = "decimal"
description = "Decimal number as string for precision"
}
typeOverride("java.math.BigInteger") {
serializedAs = "string"
format = "integer"
description = "Large integer as string"
}
}
Binary Data¶
serialOverrides {
typeOverride("kotlin.ByteArray") {
serializedAs = "string"
format = "byte"
description = "Base64 encoded binary data"
}
}
Kotlinx Datetime Types¶
If you're using kotlinx-datetime:
serialOverrides {
typeOverride("kotlinx.datetime.Instant") {
serializedAs = "string"
format = "date-time"
}
typeOverride("kotlinx.datetime.LocalDate") {
serializedAs = "string"
format = "date"
}
typeOverride("kotlinx.datetime.LocalDateTime") {
serializedAs = "string"
format = "date-time"
}
}
Custom Domain Types¶
Value Classes / Inline Classes¶
// Your code
@JvmInline
value class Email(val value: String)
@JvmInline
value class UserId(val value: Long)
// Configuration
serialOverrides {
typeOverride("com.example.Email") {
serializedAs = "string"
format = "email"
}
typeOverride("com.example.UserId") {
serializedAs = "integer"
format = "int64"
}
}
Custom ID Types¶
serialOverrides {
typeOverride("com.example.OrderId") {
serializedAs = "string"
pattern = "^ORD-[0-9]{10}$"
example = "ORD-0123456789"
}
}
Override Options¶
| Option | Type | Description |
|---|---|---|
serializedAs | String | OpenAPI type: "string", "integer", "number", "boolean", "array", "object" |
format | String? | OpenAPI format: "date-time", "date", "uuid", "email", "uri", etc. |
pattern | String? | Regex pattern for validation |
description | String? | Description of the type |
example | String? | Example value |
minimum | Number? | Minimum value (for numbers) |
maximum | Number? | Maximum value (for numbers) |
minLength | Int? | Minimum length (for strings) |
maxLength | Int? | Maximum length (for strings) |
How an Override Is Applied¶
An override with serializedAs replaces the schema derived from the class entirely: the component named after the type contains only the overridden type, plus format and description when given (falling back to the class KDoc). The class members are neither listed nor visited, so types that are only reachable through them do not appear in the specification. Usages keep referencing the component:
components:
schemas:
kotlin.time.Instant:
type: "string"
format: "date-time"
com.example.Event:
properties:
at:
$ref: "#/components/schemas/kotlin.time.Instant"
An override without serializedAs only decorates the derived schema with the given format and description.
Using Fully Qualified Names¶
Always use the fully qualified class name (including package):
// ✅ Correct
typeOverride("java.time.Instant") { ... }
typeOverride("com.myapp.domain.UserId") { ... }
// ❌ Incorrect - won't match
typeOverride("Instant") { ... }
typeOverride("UserId") { ... }
Example with Generated Schema¶
Given this data class:
data class Order(
val id: UUID,
val createdAt: Instant,
val total: BigDecimal,
val customerEmail: Email
)
With these overrides:
serialOverrides {
typeOverride("java.util.UUID") {
serializedAs = "string"
format = "uuid"
}
typeOverride("java.time.Instant") {
serializedAs = "string"
format = "date-time"
}
typeOverride("java.math.BigDecimal") {
serializedAs = "string"
format = "decimal"
}
typeOverride("com.example.Email") {
serializedAs = "string"
format = "email"
}
}
Generates:
Order:
type: object
required:
- id
- createdAt
- total
- customerEmail
properties:
id:
type: string
format: uuid
createdAt:
type: string
format: date-time
total:
type: string
format: decimal
customerEmail:
type: string
format: email
Complete Example¶
swagger {
documentation {
serialOverrides {
// Java time types
typeOverride("java.time.Instant") {
serializedAs = "string"
format = "date-time"
}
typeOverride("java.time.LocalDate") {
serializedAs = "string"
format = "date"
}
typeOverride("java.time.LocalDateTime") {
serializedAs = "string"
format = "date-time"
}
typeOverride("java.time.Duration") {
serializedAs = "string"
format = "duration"
}
// Common types
typeOverride("java.util.UUID") {
serializedAs = "string"
format = "uuid"
}
typeOverride("java.net.URI") {
serializedAs = "string"
format = "uri"
}
typeOverride("java.math.BigDecimal") {
serializedAs = "string"
format = "decimal"
}
// Kotlinx datetime (if used)
typeOverride("kotlinx.datetime.Instant") {
serializedAs = "string"
format = "date-time"
}
// Custom domain types
typeOverride("com.myapp.Email") {
serializedAs = "string"
format = "email"
}
typeOverride("com.myapp.PhoneNumber") {
serializedAs = "string"
pattern = "^\\+[1-9]\\d{1,14}$"
}
}
}
}