Skip to content

Schema Generation

The annotation processor automatically generates OpenAPI component schemas from your Java/Kotlin classes. This page covers type mappings and property-level annotations that control schema output.

Type Mappings

Primitive & Common Types

Java TypeOpenAPI TypeFormat
boolean / Booleanboolean
byte / Byteintegerint32
short / Shortintegerint32
int / Integerintegerint32
long / Longintegerint64
float / Floatnumberfloat
double / Doublenumberdouble
char / Characterstring
Stringstring
BigDecimalstring
BigIntegerinteger
UUIDstringuuid

Date & Time Types

Java TypeOpenAPI TypeFormat
java.util.Datestringdate
LocalDatestringdate
LocalDateTimestringdate-time
ZonedDateTimestringdate-time
OffsetDateTimestringdate-time
Instantstringdate-time
LocalTimestringtime
Durationstringduration

URI Types

Java TypeOpenAPI TypeFormat
URIstringuri
URLstringuri

Binary Types

Java TypeOpenAPI TypeFormat
byte[]stringbinary
InputStreamstringbinary
Filestringbinary

Collections & Maps

Java TypeOpenAPI Representation
List<T> / T[]{ "type": "array", "items": { ... } }
Map<K, V>{ "type": "object", "additionalProperties": { ... } }
Object{ "type": "object" }

Optional

java.util.Optional<T> is automatically unwrapped to a nullable T schema. For example, Optional<String> produces "type": ["string", "null"].

Property Resolution

By default, properties are resolved from getter methods following JavaBean conventions. The get / is prefix is stripped:

  • getName()name
  • isActive()active

Java Records

Record components are used directly as properties.

Field-based Resolution

Use @OpenApiByFields to resolve properties from fields instead of getters:

kotlin
@OpenApiByFields(value = Visibility.PUBLIC)
class Config {
    val host: String = ""
    val port: Int = 0
}

The value parameter controls the minimum field visibility. Use only = true to ignore methods entirely.

Property Annotations

@OpenApiIgnore

Exclude a property from the schema:

kotlin
@OpenApiIgnore
fun getInternalId(): String = ...

@OpenApiRequired

Force a property to appear in the required array:

kotlin
@OpenApiRequired
val name: String = ""

@OpenApiName

Override the property name in the schema:

kotlin
@OpenApiName("user_name")
val name: String = ""

@OpenApiDescription

Add a description to a property or class:

kotlin
@OpenApiDescription("The user's display name")
val name: String = ""

@OpenApiPropertyType

Override the schema type for a property:

kotlin
@OpenApiPropertyType(definedBy = String::class)
val id: ObjectId = ObjectId()

@OpenApiNullable

Mark a property as nullable. In OAS 3.1.0, nullable types use a type array instead of "nullable": true:

kotlin
@OpenApiNullable
val middleName: String? = null

For simple types, this produces "type": ["string", "null"]. For $ref types, nullable is expressed using anyOf:

json
{
  "field": {
    "anyOf": [
      { "$ref": "#/components/schemas/SomeType" },
      { "type": "null" }
    ]
  }
}

Recursive Types

Self-referencing types are handled via $ref:

kotlin
class TreeNode {
    val value: String = ""
    val left: TreeNode? = null
    val right: TreeNode? = null
}

The left and right properties reference #/components/schemas/TreeNode.

Generic Types

Generic type parameters are resolved when used in concrete contexts. Page<User> resolves items as an array of User.

Custom Type Mappings

Register custom type mappings in the compile-time configuration:

groovy
configuration.simpleTypeMappings['org.bson.types.ObjectId'] = new SimpleType("string")