0
# Schema and Media Types
1
2
Comprehensive schema definition system supporting OpenAPI 3.0 and 3.1 features including validation, composition, conditional schemas, and media type configuration. This system provides complete type definitions for request/response bodies, parameters, and data models.
3
4
## Capabilities
5
6
### Schema Definition
7
8
Defines comprehensive schemas for OpenAPI elements with validation, typing, and composition features.
9
10
```java { .api }
11
/**
12
* Defines schema for OpenAPI elements with extensive configuration
13
* Applied to: FIELD, METHOD, PARAMETER, TYPE, ANNOTATION_TYPE
14
*/
15
@Schema(
16
// Core schema properties
17
implementation = User.class, // Java class implementation
18
name = "UserSchema", // Schema name
19
title = "User Account", // Schema title
20
description = "User account information", // Schema description
21
22
// Composition schemas
23
not = RestrictedUser.class, // Disallowed properties class
24
oneOf = {BasicUser.class, PremiumUser.class}, // Exclusive match classes
25
anyOf = {User.class, AdminUser.class}, // Any match classes
26
allOf = {BaseUser.class, UserDetails.class}, // All match classes
27
28
// Type definitions
29
type = "object", // Schema type
30
types = {"object", "null"}, // Multiple schema types (OpenAPI 3.1)
31
format = "email", // Schema format
32
33
// Validation constraints
34
pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", // Regex pattern
35
multipleOf = 0.01, // Multiple constraint
36
maximum = "100", // Maximum value
37
exclusiveMaximum = true, // Exclusive maximum flag
38
exclusiveMaximumValue = 100.0, // Numeric exclusive maximum (OpenAPI 3.1)
39
minimum = "0", // Minimum value
40
exclusiveMinimum = false, // Exclusive minimum flag
41
exclusiveMinimumValue = 0.0, // Numeric exclusive minimum (OpenAPI 3.1)
42
maxLength = 255, // Maximum string length
43
minLength = 1, // Minimum string length
44
maxProperties = 50, // Maximum properties
45
minProperties = 1, // Minimum properties
46
47
// Property configuration
48
requiredProperties = {"email", "name"}, // Required properties
49
required = true, // Required flag (deprecated)
50
requiredMode = Schema.RequiredMode.REQUIRED, // Required mode
51
nullable = false, // Nullable flag
52
readOnly = false, // Read-only (deprecated)
53
writeOnly = false, // Write-only (deprecated)
54
accessMode = Schema.AccessMode.READ_WRITE, // Access mode
55
56
// Examples and defaults
57
example = "{\"name\":\"John\",\"email\":\"john@example.com\"}", // Example value
58
examples = {"example1", "example2"}, // Multiple example strings
59
exampleClasses = {UserExample1.class, UserExample2.class}, // Example classes
60
defaultValue = "{}", // Default value
61
_const = "constant_value", // Constant value (OpenAPI 3.1)
62
allowableValues = {"ACTIVE", "INACTIVE", "PENDING"}, // Enum values
63
64
// Property definitions
65
properties = { // Direct property definitions
66
@StringToClassMapItem(key = "userId", value = Long.class),
67
@StringToClassMapItem(key = "email", value = String.class)
68
},
69
additionalPropertiesSchema = @Schema(type = "string"), // Additional properties schema
70
patternProperties = { // Pattern-based properties
71
@StringToClassMapItem(key = "^config_.*", value = String.class)
72
},
73
propertyNames = @Schema(pattern = "^[a-zA-Z_][a-zA-Z0-9_]*$"), // Property names schema
74
75
// Array/object constraints
76
contains = User.class, // Contains constraint class
77
maxContains = 5, // Maximum contains matches
78
minContains = 1, // Minimum contains matches
79
prefixItems = {String.class, Integer.class}, // Tuple validation classes
80
additionalItems = @Schema(type = "boolean"), // Additional items schema
81
unevaluatedItems = @Schema(type = "string"), // Unevaluated items schema
82
83
// Conditional schemas (OpenAPI 3.1)
84
_if = ConditionSchema.class, // If condition schema
85
_else = ElseSchema.class, // Else condition schema
86
then = ThenSchema.class, // Then condition schema
87
88
// Dependent schemas and properties
89
dependentSchemas = { // Dependent schemas
90
@StringToClassMapItem(key = "paymentMethod", value = PaymentSchema.class)
91
},
92
dependentRequired = { // Dependent required properties
93
@DependentRequired(name = "billingAddress", value = {"street", "city"})
94
},
95
96
// Advanced features
97
discriminatorProperty = "type", // Discriminator property
98
discriminatorMapping = { // Discriminator mappings
99
@DiscriminatorMapping(value = "user", schema = User.class),
100
@DiscriminatorMapping(value = "admin", schema = AdminUser.class)
101
},
102
subTypes = {User.class, AdminUser.class}, // Subtype classes
103
schemaResolution = Schema.SchemaResolution.INLINE, // Schema resolution strategy
104
105
// Content properties (OpenAPI 3.1)
106
contentEncoding = "base64", // Content encoding
107
contentMediaType = "application/json", // Content media type
108
contentSchema = ContentDataSchema.class, // Content schema
109
110
// OpenAPI 3.1 identifiers
111
$id = "https://example.com/schemas/user", // Schema identifier
112
$schema = "https://json-schema.org/draft/2020-12/schema", // JSON Schema dialect
113
$anchor = "user-schema", // Schema anchor
114
$vocabulary = "https://example.com/vocabulary", // Schema vocabulary
115
$dynamicAnchor = "user-anchor", // Dynamic anchor
116
$comment = "User schema with validation", // Schema comment
117
118
// Metadata
119
deprecated = false, // Deprecated flag
120
hidden = false, // Hidden flag
121
enumAsRef = false, // Enum as reference
122
extensions = {@Extension(...)}, // Custom extensions
123
externalDocs = @ExternalDocumentation(...), // External documentation
124
ref = "#/components/schemas/User" // Schema reference
125
)
126
```
127
128
**Schema Internal Enums:**
129
130
```java { .api }
131
enum Schema.AccessMode {
132
AUTO, // Determine automatically
133
READ_ONLY, // Read-only access
134
WRITE_ONLY, // Write-only access
135
READ_WRITE // Full read-write access
136
}
137
138
enum Schema.RequiredMode {
139
AUTO, // Determine automatically
140
REQUIRED, // Property is required
141
NOT_REQUIRED // Property is optional
142
}
143
144
enum Schema.AdditionalPropertiesValue {
145
TRUE, // Allow additional properties
146
FALSE, // Disallow additional properties
147
USE_ADDITIONAL_PROPERTIES_ANNOTATION // Use annotation-based detection
148
}
149
150
enum Schema.SchemaResolution {
151
AUTO, // Automatic resolution
152
DEFAULT, // Default resolution
153
INLINE, // Inline schema
154
ALL_OF, // AllOf composition
155
ALL_OF_REF // AllOf with references
156
}
157
```
158
159
**Usage Examples:**
160
161
```java
162
// Basic schema on class
163
@Schema(description = "User account information")
164
public class User {
165
@Schema(description = "Unique identifier", example = "123", accessMode = Schema.AccessMode.READ_ONLY)
166
private Long id;
167
168
@Schema(
169
description = "Email address",
170
format = "email",
171
pattern = "^[^@]+@[^@]+\\.[^@]+$",
172
example = "user@example.com"
173
)
174
private String email;
175
176
@Schema(description = "User status", allowableValues = {"ACTIVE", "INACTIVE", "SUSPENDED"})
177
private UserStatus status;
178
}
179
180
// Composition schemas
181
@Schema(
182
description = "Premium user with extended features",
183
allOf = {User.class, PremiumFeatures.class}
184
)
185
public class PremiumUser {}
186
187
// Polymorphic schemas with discriminator
188
@Schema(
189
description = "Base account type",
190
discriminatorProperty = "accountType",
191
discriminatorMapping = {
192
@DiscriminatorMapping(value = "personal", schema = PersonalAccount.class),
193
@DiscriminatorMapping(value = "business", schema = BusinessAccount.class)
194
},
195
subTypes = {PersonalAccount.class, BusinessAccount.class}
196
)
197
public abstract class Account {
198
@Schema(description = "Account type discriminator")
199
private String accountType;
200
}
201
202
// Validation constraints
203
@Schema(
204
description = "Product price",
205
type = "number",
206
format = "decimal",
207
minimum = "0.01",
208
maximum = "99999.99",
209
multipleOf = 0.01,
210
example = "29.99"
211
)
212
private BigDecimal price;
213
```
214
215
### Array Schema
216
217
Defines schemas specifically for array types with additional array-specific constraints.
218
219
```java { .api }
220
/**
221
* Defines array schema with array-specific properties
222
* Applied to: FIELD, METHOD, PARAMETER, TYPE, ANNOTATION_TYPE
223
*/
224
@ArraySchema(
225
schema = @Schema(implementation = String.class), // Schema of array items
226
arraySchema = @Schema( // Properties of array itself
227
description = "List of user IDs",
228
example = "[\"123\", \"456\", \"789\"]"
229
),
230
minItems = 1, // Minimum array length
231
maxItems = 100, // Maximum array length
232
uniqueItems = true, // Items must be unique
233
extensions = {@Extension(...)}, // Custom extensions
234
235
// OpenAPI 3.1 array features
236
contains = @Schema(type = "string"), // Contains constraint
237
maxContains = 5, // Maximum contains matches
238
minContains = 1, // Minimum contains matches
239
unevaluatedItems = @Schema(type = "boolean"), // Unevaluated items schema
240
prefixItems = { // Tuple validation
241
@Schema(type = "string"),
242
@Schema(type = "integer")
243
}
244
)
245
```
246
247
**Usage Examples:**
248
249
```java
250
// String array with constraints
251
@ArraySchema(
252
schema = @Schema(type = "string", minLength = 1),
253
minItems = 1,
254
maxItems = 5,
255
uniqueItems = true
256
)
257
private List<String> tags;
258
259
// Object array
260
@ArraySchema(
261
schema = @Schema(implementation = User.class),
262
minItems = 0,
263
maxItems = 100
264
)
265
private List<User> users;
266
267
// Tuple-like array (OpenAPI 3.1)
268
@ArraySchema(
269
prefixItems = {
270
@Schema(type = "string", description = "Name"),
271
@Schema(type = "integer", description = "Age"),
272
@Schema(type = "string", description = "Email")
273
},
274
minItems = 3,
275
maxItems = 3
276
)
277
private List<Object> userTuple;
278
```
279
280
### Content Definition
281
282
Defines content/media types for parameters, request bodies, and responses with schema and examples.
283
284
```java { .api }
285
/**
286
* Defines content for different media types
287
* Applied to: within other annotations
288
*/
289
@Content(
290
mediaType = "application/json", // Media type (required)
291
schema = @Schema(implementation = User.class), // Content schema
292
schemaProperties = @SchemaProperties(...), // Schema properties
293
additionalPropertiesSchema = @Schema(...), // Additional properties schema
294
additionalPropertiesArraySchema = @ArraySchema(...), // Additional properties array
295
array = @ArraySchema(...), // Array schema alternative
296
examples = { // Multiple examples
297
@ExampleObject(name = "user1", value = "{}"),
298
@ExampleObject(name = "user2", ref = "#/components/examples/User2")
299
},
300
encoding = {@Encoding(...)}, // Encoding configurations
301
extensions = {@Extension(...)}, // Custom extensions
302
303
// OpenAPI 3.1 content features
304
dependentSchemas = @DependentSchemas(...), // Dependent schemas
305
dependentRequired = @DependentRequiredMap(...), // Dependent required properties
306
patternProperties = @PatternProperties(...), // Pattern properties
307
properties = @SchemaProperties(...), // Property definitions
308
unevaluatedProperties = @Schema(...) // Unevaluated properties schema
309
)
310
```
311
312
**Usage Examples:**
313
314
```java
315
// JSON content with schema
316
@Content(
317
mediaType = "application/json",
318
schema = @Schema(implementation = CreateUserRequest.class),
319
examples = {
320
@ExampleObject(
321
name = "basicUser",
322
summary = "Basic user creation",
323
value = "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
324
),
325
@ExampleObject(
326
name = "adminUser",
327
summary = "Admin user creation",
328
externalValue = "https://example.com/examples/admin-user.json"
329
)
330
}
331
)
332
333
// Multiple content types
334
@ApiResponse(
335
responseCode = "200",
336
content = {
337
@Content(
338
mediaType = "application/json",
339
schema = @Schema(implementation = User.class)
340
),
341
@Content(
342
mediaType = "application/xml",
343
schema = @Schema(implementation = User.class)
344
),
345
@Content(
346
mediaType = "text/plain",
347
schema = @Schema(type = "string")
348
)
349
}
350
)
351
352
// File upload content
353
@Content(
354
mediaType = "multipart/form-data",
355
encoding = {
356
@Encoding(
357
name = "file",
358
contentType = "application/octet-stream",
359
style = "form",
360
explode = false
361
),
362
@Encoding(
363
name = "metadata",
364
contentType = "application/json"
365
)
366
}
367
)
368
```
369
370
### Example Objects
371
372
Defines examples for schemas, parameters, and content with metadata and references.
373
374
```java { .api }
375
/**
376
* Defines examples with metadata
377
* Applied to: within other annotations
378
*/
379
@ExampleObject(
380
name = "userExample", // Example name
381
summary = "Basic user example", // Short summary
382
description = "Example of a basic user object", // Detailed description
383
value = "{\"id\":123,\"name\":\"John Doe\"}", // Inline example value
384
externalValue = "https://example.com/user.json", // External example URL
385
extensions = {@Extension(...)}, // Custom extensions
386
ref = "#/components/examples/BasicUser" // Reference to component example
387
)
388
```
389
390
### Schema Properties
391
392
Defines individual properties within schemas, useful for complex object definitions.
393
394
```java { .api }
395
/**
396
* Container for schema property definitions
397
*/
398
@SchemaProperties({
399
@SchemaProperty(
400
name = "userId",
401
schema = @Schema(type = "integer", format = "int64", description = "User ID")
402
),
403
@SchemaProperty(
404
name = "email",
405
schema = @Schema(type = "string", format = "email", description = "Email address")
406
)
407
})
408
409
/**
410
* Individual schema property definition
411
* Repeatable: Yes
412
*/
413
@SchemaProperty(
414
name = "propertyName", // Property name
415
schema = @Schema(...), // Property schema
416
array = @ArraySchema(...) // Array schema alternative
417
)
418
```
419
420
### Discriminator Mapping
421
422
Maps discriminator values to specific schemas for polymorphic types.
423
424
```java { .api }
425
/**
426
* Maps discriminator values to schemas
427
*/
428
@DiscriminatorMapping(
429
value = "premium", // Discriminator value
430
schema = PremiumUser.class, // Schema class for this value
431
extensions = {@Extension(...)} // Custom extensions (OpenAPI 3.1)
432
)
433
```
434
435
### Encoding Configuration
436
437
Defines encoding for multipart and form data submissions.
438
439
```java { .api }
440
/**
441
* Defines encoding for request body properties
442
*/
443
@Encoding(
444
name = "profileImage", // Property name
445
contentType = "image/png, image/jpeg", // Allowed content types
446
style = "form", // Encoding style
447
explode = true, // Explode objects/arrays
448
allowReserved = false, // Allow reserved characters
449
headers = { // Additional headers
450
@Header(name = "X-File-Type", schema = @Schema(type = "string"))
451
},
452
extensions = {@Extension(...)} // Custom extensions
453
)
454
```
455
456
**Usage Example:**
457
458
```java
459
@RequestBody(
460
content = @Content(
461
mediaType = "multipart/form-data",
462
encoding = {
463
@Encoding(
464
name = "document",
465
contentType = "application/pdf, application/msword",
466
headers = @Header(
467
name = "X-Document-Type",
468
schema = @Schema(type = "string", allowableValues = {"pdf", "doc", "docx"})
469
)
470
),
471
@Encoding(
472
name = "metadata",
473
contentType = "application/json",
474
style = "form",
475
explode = false
476
)
477
}
478
)
479
)
480
```
481
482
## OpenAPI 3.1 Advanced Features
483
484
### Dependent Schemas
485
486
Defines schemas that depend on the presence of other properties.
487
488
```java { .api }
489
/**
490
* Container for dependent schema definitions (OpenAPI 3.1)
491
*/
492
@DependentSchemas({
493
@DependentSchema(
494
name = "billingAddress",
495
schema = @Schema(
496
description = "Required when payment method is credit card",
497
required = true,
498
properties = @SchemaProperties({
499
@SchemaProperty(name = "street", schema = @Schema(type = "string")),
500
@SchemaProperty(name = "city", schema = @Schema(type = "string"))
501
})
502
)
503
)
504
})
505
506
/**
507
* Individual dependent schema (OpenAPI 3.1)
508
* Repeatable: Yes
509
*/
510
@DependentSchema(
511
name = "dependentProperty", // Property name
512
schema = @Schema(...), // Dependent schema
513
array = @ArraySchema(...) // Array schema alternative
514
)
515
```
516
517
### Dependent Required Properties
518
519
Defines properties that become required based on other properties.
520
521
```java { .api }
522
/**
523
* Container for dependent required properties (OpenAPI 3.1)
524
*/
525
@DependentRequiredMap({
526
@DependentRequired(
527
name = "paymentMethod", // Trigger property
528
value = {"cardNumber", "expiryDate", "cvv"} // Required when trigger present
529
),
530
@DependentRequired(
531
name = "shippingMethod",
532
value = {"shippingAddress"}
533
)
534
})
535
536
/**
537
* Individual dependent required definition (OpenAPI 3.1)
538
* Repeatable: Yes
539
*/
540
@DependentRequired(
541
name = "triggerProperty", // Property that triggers requirement
542
value = {"required1", "required2"} // Properties that become required
543
)
544
```
545
546
### Pattern Properties
547
548
Defines schemas for properties matching regex patterns.
549
550
```java { .api }
551
/**
552
* Container for pattern property definitions (OpenAPI 3.1)
553
*/
554
@PatternProperties({
555
@PatternProperty(
556
regex = "^[a-zA-Z]+$",
557
schema = @Schema(type = "string", description = "Alphabetic properties")
558
),
559
@PatternProperty(
560
regex = "^\\d+$",
561
schema = @Schema(type = "integer", description = "Numeric properties")
562
)
563
})
564
565
/**
566
* Individual pattern property definition (OpenAPI 3.1)
567
* Repeatable: Yes
568
*/
569
@PatternProperty(
570
regex = "^prefix_.+", // Regular expression pattern
571
schema = @Schema(...) // Schema for matching properties
572
)
573
```
574
575
**Usage Example:**
576
577
```java
578
@Schema(
579
description = "Dynamic configuration object",
580
patternProperties = @PatternProperties({
581
@PatternProperty(
582
regex = "^config_[a-zA-Z]+$",
583
schema = @Schema(type = "string", description = "Configuration values")
584
),
585
@PatternProperty(
586
regex = "^feature_[a-zA-Z]+$",
587
schema = @Schema(type = "boolean", description = "Feature flags")
588
)
589
})
590
)
591
public class DynamicConfig {
592
// Properties matching patterns will be validated accordingly
593
// e.g., config_database="localhost", feature_newUI=true
594
}
595
```
596
597
## Schema Composition Patterns
598
599
### Inheritance with AllOf
600
601
```java
602
@Schema(
603
description = "Extended user with admin privileges",
604
allOf = {User.class, AdminPrivileges.class}
605
)
606
public class AdminUser {}
607
```
608
609
### Union Types with OneOf
610
611
```java
612
@Schema(
613
description = "Payment method - either card or bank transfer",
614
oneOf = {CreditCard.class, BankTransfer.class},
615
discriminatorProperty = "type"
616
)
617
public abstract class PaymentMethod {}
618
```
619
620
### Optional Alternatives with AnyOf
621
622
```java
623
@Schema(
624
description = "User with optional contact preferences",
625
anyOf = {BasicUser.class, ContactPreferences.class}
626
)
627
public class FlexibleUser {}
628
```