0
# Core Annotations
1
2
This document covers the fundamental annotations for OpenAPI operation documentation, API definitions, parameters, and basic element configuration.
3
4
## Imports
5
6
```java { .api }
7
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
8
import io.swagger.v3.oas.annotations.Operation;
9
import io.swagger.v3.oas.annotations.Parameter;
10
import io.swagger.v3.oas.annotations.Parameters;
11
import io.swagger.v3.oas.annotations.Hidden;
12
import io.swagger.v3.oas.annotations.ExternalDocumentation;
13
import io.swagger.v3.oas.annotations.StringToClassMapItem;
14
import io.swagger.v3.oas.annotations.enums.ParameterIn;
15
import io.swagger.v3.oas.annotations.enums.ParameterStyle;
16
import io.swagger.v3.oas.annotations.enums.Explode;
17
import io.swagger.v3.oas.annotations.parameters.ValidatedParameter;
18
```
19
20
## OpenAPIDefinition
21
22
Populates OpenAPI Object fields including info, tags, servers, security, and external documentation. Applied at the class or package level to define overall API characteristics.
23
24
```java { .api }
25
@OpenAPIDefinition(
26
info = @Info(
27
title = "Pet Store API",
28
version = "1.0.0",
29
description = "A comprehensive pet store management API",
30
contact = @Contact(
31
name = "API Support",
32
url = "https://petstore.io/contact",
33
email = "support@petstore.io"
34
),
35
license = @License(
36
name = "Apache 2.0",
37
url = "https://www.apache.org/licenses/LICENSE-2.0.html"
38
)
39
),
40
tags = {
41
@Tag(name = "pets", description = "Pet operations"),
42
@Tag(name = "store", description = "Store operations"),
43
@Tag(name = "users", description = "User operations")
44
},
45
servers = {
46
@Server(
47
url = "https://api.petstore.io/v1",
48
description = "Production server"
49
),
50
@Server(
51
url = "https://staging.petstore.io/v1",
52
description = "Staging server"
53
)
54
},
55
security = @SecurityRequirement(name = "api_key"),
56
externalDocs = @ExternalDocumentation(
57
description = "Find more info here",
58
url = "https://petstore.io/docs"
59
)
60
)
61
@RestController
62
public class PetStoreApiController {
63
// API implementation
64
}
65
```
66
67
### Attributes
68
69
```java { .api }
70
public @interface OpenAPIDefinition {
71
Info info() default @Info;
72
Tag[] tags() default {};
73
Server[] servers() default {};
74
SecurityRequirement[] security() default {};
75
ExternalDocumentation externalDocs() default @ExternalDocumentation;
76
Extension[] extensions() default {};
77
}
78
```
79
80
## Operation
81
82
Defines a resource method as an OpenAPI Operation with comprehensive documentation including parameters, responses, security requirements, and metadata.
83
84
```java { .api }
85
@Operation(
86
operationId = "getPetById",
87
summary = "Find pet by ID",
88
description = "Returns a single pet based on the provided ID. " +
89
"This endpoint requires authentication and validates the pet ID parameter.",
90
tags = {"pets"},
91
method = "GET",
92
parameters = {
93
@Parameter(
94
name = "id",
95
description = "ID of pet to return",
96
required = true,
97
in = ParameterIn.PATH,
98
schema = @Schema(type = "integer", format = "int64", minimum = "1")
99
)
100
},
101
responses = {
102
@ApiResponse(
103
responseCode = "200",
104
description = "Successful operation",
105
content = @Content(
106
mediaType = "application/json",
107
schema = @Schema(implementation = Pet.class)
108
)
109
),
110
@ApiResponse(responseCode = "400", description = "Invalid ID supplied"),
111
@ApiResponse(responseCode = "404", description = "Pet not found")
112
},
113
security = @SecurityRequirement(name = "api_key"),
114
deprecated = false,
115
hidden = false,
116
externalDocs = @ExternalDocumentation(
117
description = "Learn more about pet operations",
118
url = "https://petstore.io/docs/pets"
119
)
120
)
121
@GetMapping("/pets/{id}")
122
public ResponseEntity<Pet> getPetById(@PathVariable Long id) {
123
Pet pet = petService.findById(id);
124
return ResponseEntity.ok(pet);
125
}
126
```
127
128
### Advanced Operation Configuration
129
130
```java { .api }
131
@Operation(
132
summary = "Update pet information",
133
description = "Update an existing pet's information with partial data",
134
requestBody = @RequestBody(
135
description = "Pet object with updated information",
136
required = true,
137
content = @Content(
138
mediaType = "application/json",
139
schema = @Schema(implementation = PetUpdateRequest.class),
140
examples = @ExampleObject(
141
name = "updatePetExample",
142
summary = "Example pet update",
143
value = "{ \"name\": \"Fluffy Updated\", \"status\": \"available\" }"
144
)
145
)
146
),
147
servers = {
148
@Server(url = "https://api.petstore.io/v1", description = "Primary server"),
149
@Server(url = "https://api-beta.petstore.io/v1", description = "Beta server")
150
},
151
extensions = {
152
@Extension(name = "x-rate-limit", properties = {
153
@ExtensionProperty(name = "requests", value = "100"),
154
@ExtensionProperty(name = "per", value = "minute")
155
})
156
},
157
ignoreJsonView = false
158
)
159
@PutMapping("/pets/{id}")
160
public ResponseEntity<Pet> updatePet(
161
@PathVariable Long id,
162
@Valid @RequestBody PetUpdateRequest request
163
) {
164
Pet updatedPet = petService.update(id, request);
165
return ResponseEntity.ok(updatedPet);
166
}
167
```
168
169
### Attributes
170
171
```java { .api }
172
public @interface Operation {
173
String method() default "";
174
String[] tags() default {};
175
String summary() default "";
176
String description() default "";
177
RequestBody requestBody() default @RequestBody();
178
ExternalDocumentation externalDocs() default @ExternalDocumentation();
179
String operationId() default "";
180
Parameter[] parameters() default {};
181
ApiResponse[] responses() default {};
182
boolean deprecated() default false;
183
SecurityRequirement[] security() default {};
184
Server[] servers() default {};
185
Extension[] extensions() default {};
186
boolean hidden() default false;
187
boolean ignoreJsonView() default false;
188
}
189
```
190
191
## Parameter
192
193
Defines method parameters as operation parameters with comprehensive documentation, validation constraints, and serialization options.
194
195
```java { .api }
196
@GetMapping("/pets")
197
@Operation(summary = "List pets with filtering options", tags = {"pets"})
198
public ResponseEntity<List<Pet>> listPets(
199
@Parameter(
200
name = "status",
201
description = "Status values to filter pets",
202
required = false,
203
in = ParameterIn.QUERY,
204
style = ParameterStyle.FORM,
205
explode = Explode.TRUE,
206
schema = @Schema(
207
type = "array",
208
allowableValues = {"available", "pending", "sold"}
209
),
210
examples = {
211
@ExampleObject(
212
name = "singleStatus",
213
summary = "Single status filter",
214
value = "available"
215
),
216
@ExampleObject(
217
name = "multipleStatuses",
218
summary = "Multiple status filters",
219
value = "available,pending"
220
)
221
}
222
)
223
@RequestParam(required = false) List<String> status,
224
225
@Parameter(
226
name = "category",
227
description = "Pet category ID for filtering",
228
required = false,
229
in = ParameterIn.QUERY,
230
schema = @Schema(type = "integer", format = "int64", minimum = "1"),
231
example = "1"
232
)
233
@RequestParam(required = false) Long category,
234
235
@Parameter(
236
name = "limit",
237
description = "Maximum number of pets to return",
238
required = false,
239
in = ParameterIn.QUERY,
240
schema = @Schema(
241
type = "integer",
242
format = "int32",
243
minimum = "1",
244
maximum = "100",
245
defaultValue = "20"
246
)
247
)
248
@RequestParam(defaultValue = "20") int limit,
249
250
@Parameter(
251
name = "X-Request-ID",
252
description = "Unique request identifier for tracking",
253
required = false,
254
in = ParameterIn.HEADER,
255
schema = @Schema(type = "string", format = "uuid"),
256
example = "123e4567-e89b-12d3-a456-426614174000"
257
)
258
@RequestHeader(value = "X-Request-ID", required = false) String requestId
259
) {
260
List<Pet> pets = petService.findByFilters(status, category, limit);
261
return ResponseEntity.ok(pets);
262
}
263
```
264
265
### Parameter Styles and Serialization
266
267
```java { .api }
268
// Matrix parameter style example
269
@Parameter(
270
name = "coordinates",
271
in = ParameterIn.PATH,
272
style = ParameterStyle.MATRIX,
273
explode = Explode.TRUE,
274
schema = @Schema(type = "object"),
275
description = "Geographic coordinates in matrix style"
276
)
277
278
// Label parameter style example
279
@Parameter(
280
name = "tags",
281
in = ParameterIn.PATH,
282
style = ParameterStyle.LABEL,
283
explode = Explode.FALSE,
284
schema = @Schema(type = "array", items = @Schema(type = "string")),
285
description = "Pet tags in label style"
286
)
287
288
// Deep object parameter style
289
@Parameter(
290
name = "filter",
291
in = ParameterIn.QUERY,
292
style = ParameterStyle.DEEPOBJECT,
293
explode = Explode.TRUE,
294
schema = @Schema(implementation = PetFilter.class),
295
description = "Complex filter object"
296
)
297
```
298
299
### Content-Based Parameters
300
301
```java { .api }
302
@Parameter(
303
name = "metadata",
304
description = "Complex metadata object",
305
required = false,
306
in = ParameterIn.QUERY,
307
content = {
308
@Content(
309
mediaType = "application/json",
310
schema = @Schema(implementation = PetMetadata.class),
311
examples = @ExampleObject(
312
name = "metadataExample",
313
value = "{ \"source\": \"web\", \"version\": \"1.0\" }"
314
)
315
)
316
}
317
)
318
```
319
320
### Attributes
321
322
```java { .api }
323
public @interface Parameter {
324
String name() default "";
325
ParameterIn in() default ParameterIn.DEFAULT;
326
String description() default "";
327
boolean required() default false;
328
boolean deprecated() default false;
329
boolean allowEmptyValue() default false;
330
ParameterStyle style() default ParameterStyle.DEFAULT;
331
Explode explode() default Explode.DEFAULT;
332
boolean allowReserved() default false;
333
Schema schema() default @Schema();
334
ArraySchema array() default @ArraySchema();
335
Content[] content() default {};
336
boolean hidden() default false;
337
ExampleObject[] examples() default {};
338
String example() default "";
339
Extension[] extensions() default {};
340
String ref() default "";
341
Class<?>[] validationGroups() default {};
342
}
343
```
344
345
## Parameters
346
347
Container annotation for multiple `@Parameter` annotations when applied at the method level.
348
349
```java { .api }
350
@Parameters({
351
@Parameter(
352
name = "X-API-Version",
353
description = "API version header",
354
in = ParameterIn.HEADER,
355
schema = @Schema(type = "string", defaultValue = "1.0")
356
),
357
@Parameter(
358
name = "Accept-Language",
359
description = "Preferred language for response",
360
in = ParameterIn.HEADER,
361
schema = @Schema(type = "string", defaultValue = "en-US")
362
)
363
})
364
@GetMapping("/pets/{id}")
365
public ResponseEntity<Pet> getPetById(@PathVariable Long id) {
366
return ResponseEntity.ok(petService.findById(id));
367
}
368
```
369
370
## Hidden
371
372
Marks resources, classes, or bean properties as hidden, causing them to be excluded from OpenAPI documentation generation.
373
374
```java { .api }
375
// Hide entire controller
376
@Hidden
377
@RestController
378
public class InternalController {
379
// This entire controller will be excluded from documentation
380
}
381
382
// Hide specific operation
383
@GetMapping("/pets/{id}/internal-data")
384
@Hidden
385
public ResponseEntity<String> getInternalData(@PathVariable Long id) {
386
// This operation will be excluded from documentation
387
}
388
389
// Hide specific parameter
390
public ResponseEntity<Pet> createPet(
391
@Parameter(description = "Pet data") @RequestBody Pet pet,
392
@Hidden @RequestParam String internalFlag // Hidden from docs
393
) {
394
return ResponseEntity.ok(petService.create(pet));
395
}
396
```
397
398
### Field-Level Hiding
399
400
```java { .api }
401
@Schema(description = "User profile information")
402
public class User {
403
@Schema(description = "User ID")
404
private Long id;
405
406
@Schema(description = "User name")
407
private String name;
408
409
@Hidden // This field will not appear in the schema
410
private String internalNotes;
411
412
@Schema(description = "User email", format = "email")
413
private String email;
414
}
415
```
416
417
## ExternalDocumentation
418
419
Adds references to external resources for extended documentation, commonly used with operations, schemas, and API definitions.
420
421
```java { .api }
422
@Operation(
423
summary = "Complex pet operation",
424
description = "A complex operation with detailed external documentation",
425
externalDocs = @ExternalDocumentation(
426
description = "Detailed operation guide with examples and troubleshooting",
427
url = "https://petstore.io/docs/operations/complex-pet-operation",
428
extensions = @Extension(name = "x-doc-type", properties = {
429
@ExtensionProperty(name = "type", value = "guide"),
430
@ExtensionProperty(name = "level", value = "advanced")
431
})
432
)
433
)
434
@PostMapping("/pets/complex-operation")
435
public ResponseEntity<Pet> complexPetOperation(@RequestBody ComplexPetRequest request) {
436
return ResponseEntity.ok(petService.performComplexOperation(request));
437
}
438
```
439
440
### Schema-Level External Documentation
441
442
```java { .api }
443
@Schema(
444
description = "Pet information model",
445
externalDocs = @ExternalDocumentation(
446
description = "Pet data model specification and examples",
447
url = "https://petstore.io/docs/schemas/pet"
448
)
449
)
450
public class Pet {
451
// Pet fields
452
}
453
```
454
455
### Attributes
456
457
```java { .api }
458
public @interface ExternalDocumentation {
459
String description() default "";
460
String url() default "";
461
Extension[] extensions() default {};
462
}
463
```
464
465
## StringToClassMapItem
466
467
Utility annotation for creating string-to-class mappings, typically used in complex annotation configurations that require dynamic class mapping.
468
469
```java { .api }
470
// Example usage in custom configurations
471
@StringToClassMapItem(key = "Pet", value = Pet.class)
472
@StringToClassMapItem(key = "Category", value = Category.class)
473
@StringToClassMapItem(key = "User", value = User.class)
474
public class SchemaRegistry {
475
// Class mapping configuration
476
}
477
```
478
479
### Attributes
480
481
```java { .api }
482
public @interface StringToClassMapItem {
483
String key();
484
Class<?> value();
485
}
486
```
487
488
## Enums
489
490
### ParameterIn
491
492
Defines the location of a parameter in the HTTP request.
493
494
```java { .api }
495
public enum ParameterIn {
496
DEFAULT(""),
497
HEADER("header"),
498
QUERY("query"),
499
PATH("path"),
500
COOKIE("cookie");
501
}
502
```
503
504
### ParameterStyle
505
506
Defines how parameter values are serialized based on the parameter type and location.
507
508
```java { .api }
509
public enum ParameterStyle {
510
DEFAULT, // Empty string ""
511
MATRIX, // Matrix style for path parameters - "matrix"
512
LABEL, // Label style for path parameters - "label"
513
FORM, // Form style for query and cookie parameters - "form"
514
SPACEDELIMITED, // Space separated values - "spaceDelimited"
515
PIPEDELIMITED, // Pipe separated values - "pipeDelimited"
516
DEEPOBJECT, // Deep object serialization for query parameters - "deepObject"
517
SIMPLE // Simple style for path and header parameters - "simple"
518
}
519
```
520
521
### Explode
522
523
Defines whether parameter values should be exploded (separated) or not.
524
525
```java { .api }
526
public enum Explode {
527
DEFAULT,
528
TRUE, // Parameter values are separated
529
FALSE // Parameter values are not separated
530
}
531
```
532
533
### Usage Examples for Enums
534
535
```java { .api }
536
// Query parameter with form style and exploded values
537
@Parameter(
538
name = "tags",
539
in = ParameterIn.QUERY,
540
style = ParameterStyle.FORM,
541
explode = Explode.TRUE,
542
schema = @Schema(type = "array", items = @Schema(type = "string"))
543
)
544
// Results in: ?tags=tag1&tags=tag2&tags=tag3
545
546
// Query parameter with form style and non-exploded values
547
@Parameter(
548
name = "tags",
549
in = ParameterIn.QUERY,
550
style = ParameterStyle.FORM,
551
explode = Explode.FALSE,
552
schema = @Schema(type = "array", items = @Schema(type = "string"))
553
)
554
// Results in: ?tags=tag1,tag2,tag3
555
556
// Path parameter with matrix style
557
@Parameter(
558
name = "coordinates",
559
in = ParameterIn.PATH,
560
style = ParameterStyle.MATRIX,
561
explode = Explode.TRUE,
562
schema = @Schema(type = "object")
563
)
564
// Results in: /path;lat=50.1;lng=14.4
565
566
// Cookie parameter
567
@Parameter(
568
name = "sessionId",
569
in = ParameterIn.COOKIE,
570
required = true,
571
schema = @Schema(type = "string", format = "uuid")
572
)
573
```
574
575
## ValidatedParameter
576
577
Defines validation groups for parameter validation using Bean Validation (JSR 303/349/380) annotations.
578
579
### Basic Validation Groups
580
581
```java { .api }
582
// Define validation groups
583
public interface CreateValidation {}
584
public interface UpdateValidation {}
585
586
@RestController
587
public class PetController {
588
589
@PostMapping("/pets")
590
@Operation(summary = "Create pet with validation")
591
public ResponseEntity<Pet> createPet(
592
@ValidatedParameter(groups = CreateValidation.class)
593
@Parameter(
594
description = "Pet data for creation",
595
required = true,
596
schema = @Schema(implementation = CreatePetRequest.class)
597
)
598
@Valid @RequestBody CreatePetRequest request
599
) {
600
return ResponseEntity.ok(petService.create(request));
601
}
602
603
@PutMapping("/pets/{id}")
604
@Operation(summary = "Update pet with validation")
605
public ResponseEntity<Pet> updatePet(
606
@PathVariable Long id,
607
@ValidatedParameter(groups = UpdateValidation.class)
608
@Parameter(
609
description = "Pet data for update",
610
required = true,
611
schema = @Schema(implementation = UpdatePetRequest.class)
612
)
613
@Valid @RequestBody UpdatePetRequest request
614
) {
615
return ResponseEntity.ok(petService.update(id, request));
616
}
617
}
618
```
619
620
### Multiple Validation Groups
621
622
```java { .api }
623
// Validation group interfaces
624
public interface BasicValidation {}
625
public interface AdvancedValidation {}
626
public interface AdminValidation {}
627
628
@PostMapping("/pets/advanced")
629
@Operation(summary = "Create pet with advanced validation")
630
public ResponseEntity<Pet> createAdvancedPet(
631
@ValidatedParameter(groups = {BasicValidation.class, AdvancedValidation.class})
632
@Parameter(
633
description = "Advanced pet creation request",
634
schema = @Schema(implementation = AdvancedPetRequest.class)
635
)
636
@Valid @RequestBody AdvancedPetRequest request
637
) {
638
return ResponseEntity.ok(petService.createAdvanced(request));
639
}
640
641
// Request class with validation groups
642
@Schema(description = "Advanced pet creation request")
643
public class AdvancedPetRequest {
644
@NotBlank(groups = BasicValidation.class)
645
@Size(min = 2, max = 50, groups = BasicValidation.class)
646
@Schema(description = "Pet name")
647
private String name;
648
649
@NotNull(groups = AdvancedValidation.class)
650
@Valid(groups = AdvancedValidation.class)
651
@Schema(description = "Advanced pet characteristics")
652
private PetCharacteristics characteristics;
653
654
@NotNull(groups = AdminValidation.class)
655
@Schema(description = "Internal system identifier")
656
private String internalId;
657
}
658
```
659
660
### Conditional Validation Groups
661
662
```java { .api }
663
@RestController
664
public class ConditionalValidationController {
665
666
@PostMapping("/pets/conditional")
667
@Operation(summary = "Create pet with conditional validation")
668
public ResponseEntity<Pet> createConditionalPet(
669
@ValidatedParameter(groups = {
670
BasicValidation.class,
671
ConditionalValidation.class
672
})
673
@Parameter(
674
description = "Pet creation with conditional requirements",
675
schema = @Schema(implementation = ConditionalPetRequest.class)
676
)
677
@Valid @RequestBody ConditionalPetRequest request,
678
679
@Parameter(
680
description = "Validation level",
681
in = ParameterIn.QUERY,
682
schema = @Schema(
683
type = "string",
684
allowableValues = {"basic", "advanced", "strict"},
685
defaultValue = "basic"
686
)
687
)
688
@RequestParam(defaultValue = "basic") String validationLevel
689
) {
690
// Validation logic based on level
691
return ResponseEntity.ok(petService.createWithValidation(request, validationLevel));
692
}
693
}
694
695
// Conditional validation groups
696
public interface ConditionalValidation {}
697
698
@Schema(description = "Pet request with conditional validation")
699
public class ConditionalPetRequest {
700
@NotBlank(groups = BasicValidation.class)
701
@Schema(description = "Pet name", required = true)
702
private String name;
703
704
@NotNull(groups = ConditionalValidation.class)
705
@Min(value = 0, groups = ConditionalValidation.class)
706
@Max(value = 50, groups = ConditionalValidation.class)
707
@Schema(description = "Pet age (required for advanced validation)")
708
private Integer age;
709
710
@Valid(groups = ConditionalValidation.class)
711
@Schema(description = "Health information (required for strict validation)")
712
private HealthInfo healthInfo;
713
}
714
```
715
716
### ValidatedParameter Attributes
717
718
```java { .api }
719
public @interface ValidatedParameter {
720
Class<?>[] groups() default {}; // Validation groups to apply
721
Class<?>[] value() default {}; // Alias for groups
722
}
723
```