CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-swagger-core-v3--swagger-annotations-jakarta

Jakarta EE compatible OpenAPI 3.x annotations for defining REST API specifications

Pending
Overview
Eval results
Files

responses.mddocs/

Response Management

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.

Capabilities

API Response Definition

Defines comprehensive API responses with status codes, content, headers, and links.

/**
 * Describes API response with comprehensive metadata
 * Applied to: METHOD, TYPE
 * Repeatable: Yes
 */
@ApiResponse(
    responseCode = "200",                           // HTTP response code (required)
    description = "Successful response",            // Response description (required)
    
    content = {                                     // Response content for different media types
        @Content(
            mediaType = "application/json",
            schema = @Schema(implementation = User.class),
            examples = {@ExampleObject(...)}
        ),
        @Content(
            mediaType = "application/xml",
            schema = @Schema(implementation = User.class)
        )
    },
    
    headers = {                                     // Response headers
        @Header(
            name = "X-Rate-Limit-Remaining",
            description = "Number of requests remaining",
            schema = @Schema(type = "integer")
        ),
        @Header(
            name = "X-Rate-Limit-Reset",
            description = "Rate limit reset timestamp",
            schema = @Schema(type = "integer", format = "int64")
        )
    },
    
    links = {                                       // Links to related operations
        @Link(
            name = "getUserById",
            operationId = "getUserById",
            parameters = @LinkParameter(name = "userId", expression = "$response.body#/id")
        )
    },
    
    extensions = {@Extension(...)},                 // Custom extensions
    ref = "#/components/responses/UserResponse"     // Reference to component response
)

Usage Examples:

// Success response with content
@GET
@Path("/{id}")
@Operation(summary = "Get user by ID")
@ApiResponse(
    responseCode = "200",
    description = "User found successfully",
    content = @Content(
        mediaType = "application/json",
        schema = @Schema(implementation = User.class),
        examples = @ExampleObject(
            name = "userExample",
            value = "{\"id\":123,\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
        )
    ),
    headers = {
        @Header(
            name = "Last-Modified",
            description = "Last modification timestamp",
            schema = @Schema(type = "string", format = "date-time")
        ),
        @Header(
            name = "ETag",
            description = "Entity tag for caching",
            schema = @Schema(type = "string")
        )
    }
)
@ApiResponse(
    responseCode = "404",
    description = "User not found",
    content = @Content(
        mediaType = "application/json",
        schema = @Schema(implementation = ErrorResponse.class)
    )
)
public Response getUserById(@PathParam("id") Long id) {}

// Multiple success responses based on accept header
@GET
@Operation(summary = "Get user data in multiple formats")
@ApiResponse(
    responseCode = "200",
    description = "User data",
    content = {
        @Content(
            mediaType = "application/json",
            schema = @Schema(implementation = User.class)
        ),
        @Content(
            mediaType = "application/xml",
            schema = @Schema(implementation = User.class)
        ),
        @Content(
            mediaType = "text/csv",
            schema = @Schema(type = "string", description = "CSV representation")
        )
    }
)
public Response getUserData(@PathParam("id") Long id) {}

// Response with pagination headers
@GET
@Operation(summary = "List users with pagination")
@ApiResponse(
    responseCode = "200",
    description = "User list retrieved successfully",
    content = @Content(
        mediaType = "application/json",
        schema = @Schema(implementation = UserList.class)
    ),
    headers = {
        @Header(
            name = "X-Total-Count",
            description = "Total number of users",
            schema = @Schema(type = "integer")
        ),
        @Header(
            name = "X-Page-Number", 
            description = "Current page number",
            schema = @Schema(type = "integer")
        ),
        @Header(
            name = "X-Page-Size",
            description = "Number of items per page",
            schema = @Schema(type = "integer")
        ),
        @Header(
            name = "Link",
            description = "Pagination links (next, prev, first, last)",
            schema = @Schema(type = "string")
        )
    }
)
public Response listUsers(
    @QueryParam("page") Integer page,
    @QueryParam("size") Integer size
) {}

API Responses Container

Container for multiple API response definitions on a single operation.

/**
 * Container for multiple ApiResponse annotations
 */
@ApiResponses({
    @ApiResponse(responseCode = "200", description = "Success", content = @Content(...)),
    @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(...)),
    @ApiResponse(responseCode = "401", description = "Unauthorized"),
    @ApiResponse(responseCode = "403", description = "Forbidden"),
    @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(...)),
    @ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(...))
})

Complete CRUD Response Examples:

@POST
@Operation(summary = "Create new user")
@ApiResponses({
    @ApiResponse(
        responseCode = "201",
        description = "User created successfully",
        content = @Content(
            mediaType = "application/json",
            schema = @Schema(implementation = User.class)
        ),
        headers = {
            @Header(
                name = "Location",
                description = "URL of the created user",
                schema = @Schema(type = "string", format = "uri")
            ),
            @Header(
                name = "X-Request-ID",
                description = "Request tracking ID",
                schema = @Schema(type = "string", format = "uuid")
            )
        }
    ),
    @ApiResponse(
        responseCode = "400",
        description = "Invalid user data provided",
        content = @Content(
            mediaType = "application/json",
            schema = @Schema(implementation = ValidationError.class)
        )
    ),
    @ApiResponse(
        responseCode = "409",
        description = "User with this email already exists",
        content = @Content(
            mediaType = "application/json",
            schema = @Schema(implementation = ConflictError.class)
        )
    ),
    @ApiResponse(
        responseCode = "422",
        description = "Unprocessable entity - validation failed",
        content = @Content(
            mediaType = "application/json",
            schema = @Schema(implementation = ValidationError.class)
        )
    )
})
public Response createUser(@RequestBody CreateUserRequest request) {}

@PUT
@Path("/{id}")
@Operation(summary = "Update user")
@ApiResponses({
    @ApiResponse(
        responseCode = "200",
        description = "User updated successfully",
        content = @Content(schema = @Schema(implementation = User.class))
    ),
    @ApiResponse(
        responseCode = "204",
        description = "User updated successfully (no content returned)"
    ),
    @ApiResponse(responseCode = "400", description = "Invalid update data"),
    @ApiResponse(responseCode = "404", description = "User not found"),
    @ApiResponse(responseCode = "409", description = "Update conflict (optimistic locking)")
})
public Response updateUser(@PathParam("id") Long id, @RequestBody UpdateUserRequest request) {}

@DELETE
@Path("/{id}")
@Operation(summary = "Delete user")
@ApiResponses({
    @ApiResponse(responseCode = "204", description = "User deleted successfully"),
    @ApiResponse(responseCode = "404", description = "User not found"),
    @ApiResponse(
        responseCode = "409",
        description = "Cannot delete user with active dependencies",
        content = @Content(schema = @Schema(implementation = ConflictError.class))
    )
})
public Response deleteUser(@PathParam("id") Long id) {}

Request Body Definition

Defines request body content with schema, examples, and validation requirements.

/**
 * Defines request body for operations
 * Applied to: METHOD, PARAMETER
 */
@RequestBody(
    description = "User data for creation",         // Request body description
    required = true,                                // Whether request body is required
    content = {                                     // Content for different media types
        @Content(
            mediaType = "application/json",
            schema = @Schema(implementation = CreateUserRequest.class),
            examples = {
                @ExampleObject(
                    name = "basicUser",
                    summary = "Basic user creation",
                    value = "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
                ),
                @ExampleObject(
                    name = "adminUser",
                    summary = "Admin user creation", 
                    value = "{\"name\":\"Admin User\",\"email\":\"admin@example.com\",\"role\":\"ADMIN\"}"
                )
            }
        ),
        @Content(
            mediaType = "application/xml",
            schema = @Schema(implementation = CreateUserRequest.class)
        )
    },
    extensions = {@Extension(...)},                 // Custom extensions
    ref = "#/components/requestBodies/CreateUserRequest" // Reference to component
)

Usage Examples:

// JSON request body
@POST
@Operation(summary = "Create user")
@RequestBody(
    description = "User data",
    required = true,
    content = @Content(
        mediaType = "application/json",
        schema = @Schema(implementation = CreateUserRequest.class),
        examples = @ExampleObject(
            name = "example",
            value = "{\"name\":\"John\",\"email\":\"john@example.com\",\"age\":30}"
        )
    )
)
public Response createUser(CreateUserRequest request) {}

// Multiple content types
@POST  
@Path("/upload")
@Operation(summary = "Upload user profile")
@RequestBody(
    description = "User profile data",
    required = true,
    content = {
        @Content(
            mediaType = "application/json",
            schema = @Schema(implementation = UserProfile.class)
        ),
        @Content(
            mediaType = "multipart/form-data",
            schema = @Schema(implementation = UserProfileForm.class),
            encoding = {
                @Encoding(
                    name = "profileImage",
                    contentType = "image/png, image/jpeg",
                    headers = @Header(
                        name = "X-Image-Quality",
                        schema = @Schema(type = "string", allowableValues = {"low", "medium", "high"})
                    )
                )
            }
        ),
        @Content(
            mediaType = "application/x-www-form-urlencoded",
            schema = @Schema(implementation = UserProfileForm.class)
        )
    }
)
public Response uploadProfile(UserProfileForm form) {}

// File upload request body
@POST
@Path("/documents")
@Operation(summary = "Upload document")
@RequestBody(
    description = "Document file with metadata",
    required = true,
    content = @Content(
        mediaType = "multipart/form-data",
        encoding = {
            @Encoding(
                name = "file",
                contentType = "application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                headers = {
                    @Header(
                        name = "Content-Disposition",
                        schema = @Schema(type = "string")
                    )
                }
            ),
            @Encoding(
                name = "metadata",
                contentType = "application/json"
            )
        }
    )
)
public Response uploadDocument(
    @FormParam("file") InputStream file,
    @FormParam("metadata") DocumentMetadata metadata
) {}

// Optional request body
@PUT
@Path("/{id}/preferences")
@Operation(summary = "Update user preferences")
@RequestBody(
    description = "User preferences (optional - missing fields will not be updated)",
    required = false,
    content = @Content(
        mediaType = "application/json",
        schema = @Schema(implementation = UserPreferences.class)
    )
)
public Response updatePreferences(@PathParam("id") Long id, UserPreferences preferences) {}

Response Headers

Defines headers returned in API responses with schemas and descriptions.

/**
 * Defines response header
 * Applied to: within response definitions
 */
@Header(
    name = "X-Rate-Limit-Remaining",               // Header name (required)
    description = "Number of requests remaining in current window", // Description
    required = false,                               // Whether header is always present
    deprecated = false,                             // Deprecation status
    explode = Explode.DEFAULT,                     // Explode array/object values
    hidden = false,                                // Hide from documentation
    schema = @Schema(                              // Header value schema
        type = "integer",
        minimum = "0",
        example = "42"
    ),
    array = @ArraySchema(...),                     // Array schema alternative
    example = "100",                               // Example value
    examples = {@ExampleObject(...)},              // Multiple examples
    ref = "#/components/headers/RateLimit",        // Reference to component header
    extensions = {@Extension(...)}                 // Custom extensions
)

Common Response Header Patterns:

// Rate limiting headers
@ApiResponse(
    responseCode = "200",
    description = "Success with rate limit info",
    headers = {
        @Header(
            name = "X-RateLimit-Limit",
            description = "Request limit per hour",
            schema = @Schema(type = "integer", example = "1000")
        ),
        @Header(
            name = "X-RateLimit-Remaining", 
            description = "Requests remaining in current window",
            schema = @Schema(type = "integer", example = "999")
        ),
        @Header(
            name = "X-RateLimit-Reset",
            description = "Time when rate limit resets",
            schema = @Schema(type = "integer", format = "int64", example = "1640995200")
        )
    }
)

// Caching headers
@ApiResponse(
    responseCode = "200",
    description = "Success with caching headers",
    headers = {
        @Header(
            name = "ETag",
            description = "Entity tag for caching",
            schema = @Schema(type = "string", example = "\"abc123\"")
        ),
        @Header(
            name = "Last-Modified",
            description = "Last modification time",
            schema = @Schema(type = "string", format = "date-time")
        ),
        @Header(
            name = "Cache-Control",
            description = "Cache control directives",
            schema = @Schema(type = "string", example = "max-age=3600, must-revalidate")
        )
    }
)

// CORS headers
@ApiResponse(
    responseCode = "200", 
    description = "Success with CORS headers",
    headers = {
        @Header(
            name = "Access-Control-Allow-Origin",
            description = "Allowed origins for CORS",
            schema = @Schema(type = "string", example = "https://example.com")
        ),
        @Header(
            name = "Access-Control-Allow-Methods",
            description = "Allowed HTTP methods",
            schema = @Schema(type = "string", example = "GET, POST, PUT, DELETE")
        ),
        @Header(
            name = "Access-Control-Allow-Headers",
            description = "Allowed request headers",
            schema = @Schema(type = "string", example = "Content-Type, Authorization")
        )
    }
)

// Location header for created resources
@ApiResponse(
    responseCode = "201",
    description = "Resource created successfully",
    headers = @Header(
        name = "Location",
        description = "URL of the created resource",
        required = true,
        schema = @Schema(type = "string", format = "uri", example = "https://api.example.com/users/123")
    )
)

// Content disposition for file downloads
@ApiResponse(
    responseCode = "200",
    description = "File download",
    content = @Content(
        mediaType = "application/octet-stream",
        schema = @Schema(type = "string", format = "binary")
    ),
    headers = {
        @Header(
            name = "Content-Disposition",
            description = "File download disposition",
            schema = @Schema(type = "string", example = "attachment; filename=\"report.pdf\"")
        ),
        @Header(
            name = "Content-Length",
            description = "File size in bytes",
            schema = @Schema(type = "integer", format = "int64")
        )
    }
)

Operation Links

Defines links between operations to describe workflows and related actions.

/**
 * Defines link to related operation
 * Applied to: within response definitions
 */
@Link(
    name = "getUserById",                           // Link name (required)
    operationRef = "#/paths/~1users~1{userId}/get", // Reference to operation
    operationId = "getUserById",                    // Operation ID reference
    parameters = {                                  // Parameters to pass to linked operation
        @LinkParameter(name = "userId", expression = "$response.body#/id")
    },
    requestBody = "$response.body#/userDetails",    // Request body for linked operation
    description = "Get the created user details",   // Link description
    server = @Server(...),                          // Alternative server for link
    extensions = {@Extension(...)},                 // Custom extensions
    ref = "#/components/links/GetUserById"          // Reference to component link
)

/**
 * Link parameter definition
 */
@LinkParameter(
    name = "userId",                                // Parameter name (required)
    expression = "$response.body#/id"               // Expression to get parameter value
)

Link Expression Examples:

// Response body field
@LinkParameter(name = "userId", expression = "$response.body#/id")

// Response header value  
@LinkParameter(name = "etag", expression = "$response.header.ETag")

// Query parameter from current request
@LinkParameter(name = "include", expression = "$request.query.include")

// Path parameter from current request
@LinkParameter(name = "version", expression = "$request.path.version")

// Constant value
@LinkParameter(name = "format", expression = "json")

Usage Examples:

@POST
@Operation(summary = "Create user")
@ApiResponse(
    responseCode = "201",
    description = "User created successfully",
    content = @Content(schema = @Schema(implementation = User.class)),
    links = {
        @Link(
            name = "GetUserById",
            description = "Get the created user",
            operationId = "getUserById",
            parameters = @LinkParameter(name = "id", expression = "$response.body#/id")
        ),
        @Link(
            name = "UpdateUser",
            description = "Update the created user",
            operationId = "updateUser", 
            parameters = @LinkParameter(name = "id", expression = "$response.body#/id")
        ),
        @Link(
            name = "DeleteUser",
            description = "Delete the created user",
            operationId = "deleteUser",
            parameters = @LinkParameter(name = "id", expression = "$response.body#/id")
        )
    }
)
public Response createUser(@RequestBody CreateUserRequest request) {}

@GET
@Path("/{id}")
@Operation(operationId = "getUserById", summary = "Get user by ID")
@ApiResponse(
    responseCode = "200",
    description = "User retrieved successfully",
    content = @Content(schema = @Schema(implementation = User.class)),
    links = {
        @Link(
            name = "GetUserPosts",
            description = "Get posts by this user",
            operationId = "getPostsByUserId",
            parameters = @LinkParameter(name = "userId", expression = "$response.body#/id")
        ),
        @Link(
            name = "GetUserProfile",
            description = "Get user profile",
            operationId = "getUserProfile",
            parameters = @LinkParameter(name = "userId", expression = "$response.body#/id")
        )
    }
)
public Response getUserById(@PathParam("id") Long id) {}

Error Response Patterns

Standard Error Responses

// Standard error schema
@Schema(description = "Standard error response")
public class ErrorResponse {
    @Schema(description = "Error code", example = "USER_NOT_FOUND")
    private String code;
    
    @Schema(description = "Human-readable error message", example = "User with ID 123 not found")
    private String message;
    
    @Schema(description = "Request timestamp", format = "date-time")
    private String timestamp;
    
    @Schema(description = "Request tracking ID", format = "uuid") 
    private String requestId;
}

// Validation error schema
@Schema(description = "Validation error with field details")
public class ValidationError extends ErrorResponse {
    @Schema(description = "Field-specific validation errors")
    private List<FieldError> fieldErrors;
}

@Schema(description = "Individual field validation error")
public class FieldError {
    @Schema(description = "Field name", example = "email")
    private String field;
    
    @Schema(description = "Invalid value", example = "not-an-email")
    private String rejectedValue;
    
    @Schema(description = "Validation message", example = "must be a valid email address")
    private String message;
}

Complete Error Response Set

@ApiResponses({
    @ApiResponse(responseCode = "200", description = "Success"),
    @ApiResponse(
        responseCode = "400",
        description = "Bad Request - Invalid input data",
        content = @Content(
            mediaType = "application/json",
            schema = @Schema(implementation = ValidationError.class),
            examples = @ExampleObject(
                name = "validationError",
                value = "{\"code\":\"VALIDATION_ERROR\",\"message\":\"Invalid input\",\"fieldErrors\":[{\"field\":\"email\",\"message\":\"Invalid email format\"}]}"
            )
        )
    ),
    @ApiResponse(
        responseCode = "401", 
        description = "Unauthorized - Authentication required",
        content = @Content(schema = @Schema(implementation = ErrorResponse.class))
    ),
    @ApiResponse(
        responseCode = "403",
        description = "Forbidden - Insufficient permissions",
        content = @Content(schema = @Schema(implementation = ErrorResponse.class))
    ),
    @ApiResponse(
        responseCode = "404",
        description = "Not Found - Resource does not exist",
        content = @Content(schema = @Schema(implementation = ErrorResponse.class))
    ),
    @ApiResponse(
        responseCode = "429",
        description = "Too Many Requests - Rate limit exceeded",
        content = @Content(schema = @Schema(implementation = ErrorResponse.class)),
        headers = {
            @Header(name = "Retry-After", schema = @Schema(type = "integer", description = "Seconds to wait"))
        }
    ),
    @ApiResponse(
        responseCode = "500",
        description = "Internal Server Error",
        content = @Content(schema = @Schema(implementation = ErrorResponse.class))
    )
})

Install with Tessl CLI

npx tessl i tessl/maven-io-swagger-core-v3--swagger-annotations-jakarta

docs

callbacks.md

core-annotations.md

enums.md

index.md

links.md

responses.md

schema-media.md

security.md

server-info.md

tile.json