0
# Response Management
1
2
Structured response documentation with status codes, content types, headers, request bodies, and linking between operations. This system provides comprehensive response definitions for REST API operations including success responses, error responses, and complex data flows.
3
4
## Capabilities
5
6
### API Response Definition
7
8
Defines comprehensive API responses with status codes, content, headers, and links.
9
10
```java { .api }
11
/**
12
* Describes API response with comprehensive metadata
13
* Applied to: METHOD, TYPE
14
* Repeatable: Yes
15
*/
16
@ApiResponse(
17
responseCode = "200", // HTTP response code (required)
18
description = "Successful response", // Response description (required)
19
20
content = { // Response content for different media types
21
@Content(
22
mediaType = "application/json",
23
schema = @Schema(implementation = User.class),
24
examples = {@ExampleObject(...)}
25
),
26
@Content(
27
mediaType = "application/xml",
28
schema = @Schema(implementation = User.class)
29
)
30
},
31
32
headers = { // Response headers
33
@Header(
34
name = "X-Rate-Limit-Remaining",
35
description = "Number of requests remaining",
36
schema = @Schema(type = "integer")
37
),
38
@Header(
39
name = "X-Rate-Limit-Reset",
40
description = "Rate limit reset timestamp",
41
schema = @Schema(type = "integer", format = "int64")
42
)
43
},
44
45
links = { // Links to related operations
46
@Link(
47
name = "getUserById",
48
operationId = "getUserById",
49
parameters = @LinkParameter(name = "userId", expression = "$response.body#/id")
50
)
51
},
52
53
extensions = {@Extension(...)}, // Custom extensions
54
ref = "#/components/responses/UserResponse" // Reference to component response
55
)
56
```
57
58
**Usage Examples:**
59
60
```java
61
// Success response with content
62
@GET
63
@Path("/{id}")
64
@Operation(summary = "Get user by ID")
65
@ApiResponse(
66
responseCode = "200",
67
description = "User found successfully",
68
content = @Content(
69
mediaType = "application/json",
70
schema = @Schema(implementation = User.class),
71
examples = @ExampleObject(
72
name = "userExample",
73
value = "{\"id\":123,\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
74
)
75
),
76
headers = {
77
@Header(
78
name = "Last-Modified",
79
description = "Last modification timestamp",
80
schema = @Schema(type = "string", format = "date-time")
81
),
82
@Header(
83
name = "ETag",
84
description = "Entity tag for caching",
85
schema = @Schema(type = "string")
86
)
87
}
88
)
89
@ApiResponse(
90
responseCode = "404",
91
description = "User not found",
92
content = @Content(
93
mediaType = "application/json",
94
schema = @Schema(implementation = ErrorResponse.class)
95
)
96
)
97
public Response getUserById(@PathParam("id") Long id) {}
98
99
// Multiple success responses based on accept header
100
@GET
101
@Operation(summary = "Get user data in multiple formats")
102
@ApiResponse(
103
responseCode = "200",
104
description = "User data",
105
content = {
106
@Content(
107
mediaType = "application/json",
108
schema = @Schema(implementation = User.class)
109
),
110
@Content(
111
mediaType = "application/xml",
112
schema = @Schema(implementation = User.class)
113
),
114
@Content(
115
mediaType = "text/csv",
116
schema = @Schema(type = "string", description = "CSV representation")
117
)
118
}
119
)
120
public Response getUserData(@PathParam("id") Long id) {}
121
122
// Response with pagination headers
123
@GET
124
@Operation(summary = "List users with pagination")
125
@ApiResponse(
126
responseCode = "200",
127
description = "User list retrieved successfully",
128
content = @Content(
129
mediaType = "application/json",
130
schema = @Schema(implementation = UserList.class)
131
),
132
headers = {
133
@Header(
134
name = "X-Total-Count",
135
description = "Total number of users",
136
schema = @Schema(type = "integer")
137
),
138
@Header(
139
name = "X-Page-Number",
140
description = "Current page number",
141
schema = @Schema(type = "integer")
142
),
143
@Header(
144
name = "X-Page-Size",
145
description = "Number of items per page",
146
schema = @Schema(type = "integer")
147
),
148
@Header(
149
name = "Link",
150
description = "Pagination links (next, prev, first, last)",
151
schema = @Schema(type = "string")
152
)
153
}
154
)
155
public Response listUsers(
156
@QueryParam("page") Integer page,
157
@QueryParam("size") Integer size
158
) {}
159
```
160
161
### API Responses Container
162
163
Container for multiple API response definitions on a single operation.
164
165
```java { .api }
166
/**
167
* Container for multiple ApiResponse annotations
168
*/
169
@ApiResponses({
170
@ApiResponse(responseCode = "200", description = "Success", content = @Content(...)),
171
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(...)),
172
@ApiResponse(responseCode = "401", description = "Unauthorized"),
173
@ApiResponse(responseCode = "403", description = "Forbidden"),
174
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(...)),
175
@ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(...))
176
})
177
```
178
179
**Complete CRUD Response Examples:**
180
181
```java
182
@POST
183
@Operation(summary = "Create new user")
184
@ApiResponses({
185
@ApiResponse(
186
responseCode = "201",
187
description = "User created successfully",
188
content = @Content(
189
mediaType = "application/json",
190
schema = @Schema(implementation = User.class)
191
),
192
headers = {
193
@Header(
194
name = "Location",
195
description = "URL of the created user",
196
schema = @Schema(type = "string", format = "uri")
197
),
198
@Header(
199
name = "X-Request-ID",
200
description = "Request tracking ID",
201
schema = @Schema(type = "string", format = "uuid")
202
)
203
}
204
),
205
@ApiResponse(
206
responseCode = "400",
207
description = "Invalid user data provided",
208
content = @Content(
209
mediaType = "application/json",
210
schema = @Schema(implementation = ValidationError.class)
211
)
212
),
213
@ApiResponse(
214
responseCode = "409",
215
description = "User with this email already exists",
216
content = @Content(
217
mediaType = "application/json",
218
schema = @Schema(implementation = ConflictError.class)
219
)
220
),
221
@ApiResponse(
222
responseCode = "422",
223
description = "Unprocessable entity - validation failed",
224
content = @Content(
225
mediaType = "application/json",
226
schema = @Schema(implementation = ValidationError.class)
227
)
228
)
229
})
230
public Response createUser(@RequestBody CreateUserRequest request) {}
231
232
@PUT
233
@Path("/{id}")
234
@Operation(summary = "Update user")
235
@ApiResponses({
236
@ApiResponse(
237
responseCode = "200",
238
description = "User updated successfully",
239
content = @Content(schema = @Schema(implementation = User.class))
240
),
241
@ApiResponse(
242
responseCode = "204",
243
description = "User updated successfully (no content returned)"
244
),
245
@ApiResponse(responseCode = "400", description = "Invalid update data"),
246
@ApiResponse(responseCode = "404", description = "User not found"),
247
@ApiResponse(responseCode = "409", description = "Update conflict (optimistic locking)")
248
})
249
public Response updateUser(@PathParam("id") Long id, @RequestBody UpdateUserRequest request) {}
250
251
@DELETE
252
@Path("/{id}")
253
@Operation(summary = "Delete user")
254
@ApiResponses({
255
@ApiResponse(responseCode = "204", description = "User deleted successfully"),
256
@ApiResponse(responseCode = "404", description = "User not found"),
257
@ApiResponse(
258
responseCode = "409",
259
description = "Cannot delete user with active dependencies",
260
content = @Content(schema = @Schema(implementation = ConflictError.class))
261
)
262
})
263
public Response deleteUser(@PathParam("id") Long id) {}
264
```
265
266
### Request Body Definition
267
268
Defines request body content with schema, examples, and validation requirements.
269
270
```java { .api }
271
/**
272
* Defines request body for operations
273
* Applied to: METHOD, PARAMETER
274
*/
275
@RequestBody(
276
description = "User data for creation", // Request body description
277
required = true, // Whether request body is required
278
content = { // Content for different media types
279
@Content(
280
mediaType = "application/json",
281
schema = @Schema(implementation = CreateUserRequest.class),
282
examples = {
283
@ExampleObject(
284
name = "basicUser",
285
summary = "Basic user creation",
286
value = "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
287
),
288
@ExampleObject(
289
name = "adminUser",
290
summary = "Admin user creation",
291
value = "{\"name\":\"Admin User\",\"email\":\"admin@example.com\",\"role\":\"ADMIN\"}"
292
)
293
}
294
),
295
@Content(
296
mediaType = "application/xml",
297
schema = @Schema(implementation = CreateUserRequest.class)
298
)
299
},
300
extensions = {@Extension(...)}, // Custom extensions
301
ref = "#/components/requestBodies/CreateUserRequest" // Reference to component
302
)
303
```
304
305
**Usage Examples:**
306
307
```java
308
// JSON request body
309
@POST
310
@Operation(summary = "Create user")
311
@RequestBody(
312
description = "User data",
313
required = true,
314
content = @Content(
315
mediaType = "application/json",
316
schema = @Schema(implementation = CreateUserRequest.class),
317
examples = @ExampleObject(
318
name = "example",
319
value = "{\"name\":\"John\",\"email\":\"john@example.com\",\"age\":30}"
320
)
321
)
322
)
323
public Response createUser(CreateUserRequest request) {}
324
325
// Multiple content types
326
@POST
327
@Path("/upload")
328
@Operation(summary = "Upload user profile")
329
@RequestBody(
330
description = "User profile data",
331
required = true,
332
content = {
333
@Content(
334
mediaType = "application/json",
335
schema = @Schema(implementation = UserProfile.class)
336
),
337
@Content(
338
mediaType = "multipart/form-data",
339
schema = @Schema(implementation = UserProfileForm.class),
340
encoding = {
341
@Encoding(
342
name = "profileImage",
343
contentType = "image/png, image/jpeg",
344
headers = @Header(
345
name = "X-Image-Quality",
346
schema = @Schema(type = "string", allowableValues = {"low", "medium", "high"})
347
)
348
)
349
}
350
),
351
@Content(
352
mediaType = "application/x-www-form-urlencoded",
353
schema = @Schema(implementation = UserProfileForm.class)
354
)
355
}
356
)
357
public Response uploadProfile(UserProfileForm form) {}
358
359
// File upload request body
360
@POST
361
@Path("/documents")
362
@Operation(summary = "Upload document")
363
@RequestBody(
364
description = "Document file with metadata",
365
required = true,
366
content = @Content(
367
mediaType = "multipart/form-data",
368
encoding = {
369
@Encoding(
370
name = "file",
371
contentType = "application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document",
372
headers = {
373
@Header(
374
name = "Content-Disposition",
375
schema = @Schema(type = "string")
376
)
377
}
378
),
379
@Encoding(
380
name = "metadata",
381
contentType = "application/json"
382
)
383
}
384
)
385
)
386
public Response uploadDocument(
387
@FormParam("file") InputStream file,
388
@FormParam("metadata") DocumentMetadata metadata
389
) {}
390
391
// Optional request body
392
@PUT
393
@Path("/{id}/preferences")
394
@Operation(summary = "Update user preferences")
395
@RequestBody(
396
description = "User preferences (optional - missing fields will not be updated)",
397
required = false,
398
content = @Content(
399
mediaType = "application/json",
400
schema = @Schema(implementation = UserPreferences.class)
401
)
402
)
403
public Response updatePreferences(@PathParam("id") Long id, UserPreferences preferences) {}
404
```
405
406
### Response Headers
407
408
Defines headers returned in API responses with schemas and descriptions.
409
410
```java { .api }
411
/**
412
* Defines response header
413
* Applied to: within response definitions
414
*/
415
@Header(
416
name = "X-Rate-Limit-Remaining", // Header name (required)
417
description = "Number of requests remaining in current window", // Description
418
required = false, // Whether header is always present
419
deprecated = false, // Deprecation status
420
explode = Explode.DEFAULT, // Explode array/object values
421
hidden = false, // Hide from documentation
422
schema = @Schema( // Header value schema
423
type = "integer",
424
minimum = "0",
425
example = "42"
426
),
427
array = @ArraySchema(...), // Array schema alternative
428
example = "100", // Example value
429
examples = {@ExampleObject(...)}, // Multiple examples
430
ref = "#/components/headers/RateLimit", // Reference to component header
431
extensions = {@Extension(...)} // Custom extensions
432
)
433
```
434
435
**Common Response Header Patterns:**
436
437
```java
438
// Rate limiting headers
439
@ApiResponse(
440
responseCode = "200",
441
description = "Success with rate limit info",
442
headers = {
443
@Header(
444
name = "X-RateLimit-Limit",
445
description = "Request limit per hour",
446
schema = @Schema(type = "integer", example = "1000")
447
),
448
@Header(
449
name = "X-RateLimit-Remaining",
450
description = "Requests remaining in current window",
451
schema = @Schema(type = "integer", example = "999")
452
),
453
@Header(
454
name = "X-RateLimit-Reset",
455
description = "Time when rate limit resets",
456
schema = @Schema(type = "integer", format = "int64", example = "1640995200")
457
)
458
}
459
)
460
461
// Caching headers
462
@ApiResponse(
463
responseCode = "200",
464
description = "Success with caching headers",
465
headers = {
466
@Header(
467
name = "ETag",
468
description = "Entity tag for caching",
469
schema = @Schema(type = "string", example = "\"abc123\"")
470
),
471
@Header(
472
name = "Last-Modified",
473
description = "Last modification time",
474
schema = @Schema(type = "string", format = "date-time")
475
),
476
@Header(
477
name = "Cache-Control",
478
description = "Cache control directives",
479
schema = @Schema(type = "string", example = "max-age=3600, must-revalidate")
480
)
481
}
482
)
483
484
// CORS headers
485
@ApiResponse(
486
responseCode = "200",
487
description = "Success with CORS headers",
488
headers = {
489
@Header(
490
name = "Access-Control-Allow-Origin",
491
description = "Allowed origins for CORS",
492
schema = @Schema(type = "string", example = "https://example.com")
493
),
494
@Header(
495
name = "Access-Control-Allow-Methods",
496
description = "Allowed HTTP methods",
497
schema = @Schema(type = "string", example = "GET, POST, PUT, DELETE")
498
),
499
@Header(
500
name = "Access-Control-Allow-Headers",
501
description = "Allowed request headers",
502
schema = @Schema(type = "string", example = "Content-Type, Authorization")
503
)
504
}
505
)
506
507
// Location header for created resources
508
@ApiResponse(
509
responseCode = "201",
510
description = "Resource created successfully",
511
headers = @Header(
512
name = "Location",
513
description = "URL of the created resource",
514
required = true,
515
schema = @Schema(type = "string", format = "uri", example = "https://api.example.com/users/123")
516
)
517
)
518
519
// Content disposition for file downloads
520
@ApiResponse(
521
responseCode = "200",
522
description = "File download",
523
content = @Content(
524
mediaType = "application/octet-stream",
525
schema = @Schema(type = "string", format = "binary")
526
),
527
headers = {
528
@Header(
529
name = "Content-Disposition",
530
description = "File download disposition",
531
schema = @Schema(type = "string", example = "attachment; filename=\"report.pdf\"")
532
),
533
@Header(
534
name = "Content-Length",
535
description = "File size in bytes",
536
schema = @Schema(type = "integer", format = "int64")
537
)
538
}
539
)
540
```
541
542
### Operation Links
543
544
Defines links between operations to describe workflows and related actions.
545
546
```java { .api }
547
/**
548
* Defines link to related operation
549
* Applied to: within response definitions
550
*/
551
@Link(
552
name = "getUserById", // Link name (required)
553
operationRef = "#/paths/~1users~1{userId}/get", // Reference to operation
554
operationId = "getUserById", // Operation ID reference
555
parameters = { // Parameters to pass to linked operation
556
@LinkParameter(name = "userId", expression = "$response.body#/id")
557
},
558
requestBody = "$response.body#/userDetails", // Request body for linked operation
559
description = "Get the created user details", // Link description
560
server = @Server(...), // Alternative server for link
561
extensions = {@Extension(...)}, // Custom extensions
562
ref = "#/components/links/GetUserById" // Reference to component link
563
)
564
565
/**
566
* Link parameter definition
567
*/
568
@LinkParameter(
569
name = "userId", // Parameter name (required)
570
expression = "$response.body#/id" // Expression to get parameter value
571
)
572
```
573
574
**Link Expression Examples:**
575
576
```java
577
// Response body field
578
@LinkParameter(name = "userId", expression = "$response.body#/id")
579
580
// Response header value
581
@LinkParameter(name = "etag", expression = "$response.header.ETag")
582
583
// Query parameter from current request
584
@LinkParameter(name = "include", expression = "$request.query.include")
585
586
// Path parameter from current request
587
@LinkParameter(name = "version", expression = "$request.path.version")
588
589
// Constant value
590
@LinkParameter(name = "format", expression = "json")
591
```
592
593
**Usage Examples:**
594
595
```java
596
@POST
597
@Operation(summary = "Create user")
598
@ApiResponse(
599
responseCode = "201",
600
description = "User created successfully",
601
content = @Content(schema = @Schema(implementation = User.class)),
602
links = {
603
@Link(
604
name = "GetUserById",
605
description = "Get the created user",
606
operationId = "getUserById",
607
parameters = @LinkParameter(name = "id", expression = "$response.body#/id")
608
),
609
@Link(
610
name = "UpdateUser",
611
description = "Update the created user",
612
operationId = "updateUser",
613
parameters = @LinkParameter(name = "id", expression = "$response.body#/id")
614
),
615
@Link(
616
name = "DeleteUser",
617
description = "Delete the created user",
618
operationId = "deleteUser",
619
parameters = @LinkParameter(name = "id", expression = "$response.body#/id")
620
)
621
}
622
)
623
public Response createUser(@RequestBody CreateUserRequest request) {}
624
625
@GET
626
@Path("/{id}")
627
@Operation(operationId = "getUserById", summary = "Get user by ID")
628
@ApiResponse(
629
responseCode = "200",
630
description = "User retrieved successfully",
631
content = @Content(schema = @Schema(implementation = User.class)),
632
links = {
633
@Link(
634
name = "GetUserPosts",
635
description = "Get posts by this user",
636
operationId = "getPostsByUserId",
637
parameters = @LinkParameter(name = "userId", expression = "$response.body#/id")
638
),
639
@Link(
640
name = "GetUserProfile",
641
description = "Get user profile",
642
operationId = "getUserProfile",
643
parameters = @LinkParameter(name = "userId", expression = "$response.body#/id")
644
)
645
}
646
)
647
public Response getUserById(@PathParam("id") Long id) {}
648
```
649
650
## Error Response Patterns
651
652
### Standard Error Responses
653
654
```java
655
// Standard error schema
656
@Schema(description = "Standard error response")
657
public class ErrorResponse {
658
@Schema(description = "Error code", example = "USER_NOT_FOUND")
659
private String code;
660
661
@Schema(description = "Human-readable error message", example = "User with ID 123 not found")
662
private String message;
663
664
@Schema(description = "Request timestamp", format = "date-time")
665
private String timestamp;
666
667
@Schema(description = "Request tracking ID", format = "uuid")
668
private String requestId;
669
}
670
671
// Validation error schema
672
@Schema(description = "Validation error with field details")
673
public class ValidationError extends ErrorResponse {
674
@Schema(description = "Field-specific validation errors")
675
private List<FieldError> fieldErrors;
676
}
677
678
@Schema(description = "Individual field validation error")
679
public class FieldError {
680
@Schema(description = "Field name", example = "email")
681
private String field;
682
683
@Schema(description = "Invalid value", example = "not-an-email")
684
private String rejectedValue;
685
686
@Schema(description = "Validation message", example = "must be a valid email address")
687
private String message;
688
}
689
```
690
691
### Complete Error Response Set
692
693
```java
694
@ApiResponses({
695
@ApiResponse(responseCode = "200", description = "Success"),
696
@ApiResponse(
697
responseCode = "400",
698
description = "Bad Request - Invalid input data",
699
content = @Content(
700
mediaType = "application/json",
701
schema = @Schema(implementation = ValidationError.class),
702
examples = @ExampleObject(
703
name = "validationError",
704
value = "{\"code\":\"VALIDATION_ERROR\",\"message\":\"Invalid input\",\"fieldErrors\":[{\"field\":\"email\",\"message\":\"Invalid email format\"}]}"
705
)
706
)
707
),
708
@ApiResponse(
709
responseCode = "401",
710
description = "Unauthorized - Authentication required",
711
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
712
),
713
@ApiResponse(
714
responseCode = "403",
715
description = "Forbidden - Insufficient permissions",
716
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
717
),
718
@ApiResponse(
719
responseCode = "404",
720
description = "Not Found - Resource does not exist",
721
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
722
),
723
@ApiResponse(
724
responseCode = "429",
725
description = "Too Many Requests - Rate limit exceeded",
726
content = @Content(schema = @Schema(implementation = ErrorResponse.class)),
727
headers = {
728
@Header(name = "Retry-After", schema = @Schema(type = "integer", description = "Seconds to wait"))
729
}
730
),
731
@ApiResponse(
732
responseCode = "500",
733
description = "Internal Server Error",
734
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
735
)
736
})
737
```