CtrlK
BlogDocsLog inGet started
Tessl Logo

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

Swagger Core annotations library providing OpenAPI 3.x annotations for Java applications, enabling developers to document REST APIs with metadata annotations

Pending
Overview
Eval results
Files

advanced-features.mddocs/

Advanced Features

This document covers advanced OpenAPI annotations including extensions, callbacks for asynchronous operations, webhooks, links between operations, and OpenAPI 3.1 enhanced features.

Imports

import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.Extensions;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.callbacks.Callback;
import io.swagger.v3.oas.annotations.callbacks.Callbacks;
import io.swagger.v3.oas.annotations.Webhook;
import io.swagger.v3.oas.annotations.Webhooks;
import io.swagger.v3.oas.annotations.links.Link;
import io.swagger.v3.oas.annotations.links.LinkParameter;
import io.swagger.v3.oas.annotations.headers.Header;
import io.swagger.v3.oas.annotations.OpenAPI31;

Extensions

OpenAPI extensions allow you to add vendor-specific or custom properties to your API specification using the x- prefix convention.

Basic Extensions

@Operation(
    summary = "Get pet by ID",
    extensions = {
        @Extension(name = "x-rate-limit", properties = {
            @ExtensionProperty(name = "requests", value = "100"),
            @ExtensionProperty(name = "period", value = "minute")
        }),
        @Extension(name = "x-cache-duration", properties = {
            @ExtensionProperty(name = "seconds", value = "300")
        })
    }
)
@GetMapping("/pets/{id}")
public ResponseEntity<Pet> getPetById(@PathVariable Long id) {
    return ResponseEntity.ok(petService.findById(id));
}

Schema Extensions

@Schema(
    description = "Pet information with enhanced metadata",
    extensions = {
        @Extension(name = "x-data-classification", properties = {
            @ExtensionProperty(name = "level", value = "public"),
            @ExtensionProperty(name = "retention", value = "7-years"),
            @ExtensionProperty(name = "pii", value = "false")
        }),
        @Extension(name = "x-validation-rules", properties = {
            @ExtensionProperty(name = "custom-validator", value = "PetNameValidator"),
            @ExtensionProperty(name = "business-rules", value = "no-duplicate-names-per-owner")
        }),
        @Extension(name = "x-ui-hints", properties = {
            @ExtensionProperty(name = "display-order", value = "name,category,status,tags"),
            @ExtensionProperty(name = "required-highlight", value = "true"),
            @ExtensionProperty(name = "collapse-advanced", value = "true")
        })
    }
)
public class Pet {
    @Schema(
        description = "Pet name",
        extensions = {
            @Extension(name = "x-input-validation", properties = {
                @ExtensionProperty(name = "trim-whitespace", value = "true"),
                @ExtensionProperty(name = "capitalize-first", value = "true")
            })
        }
    )
    private String name;
    
    @Schema(
        description = "Pet status",
        extensions = {
            @Extension(name = "x-state-machine", properties = {
                @ExtensionProperty(name = "transitions", value = "available->pending,pending->sold,sold->available"),
                @ExtensionProperty(name = "initial-state", value = "available")
            })
        }
    )
    private String status;
}

API-Level Extensions

@OpenAPIDefinition(
    info = @Info(
        title = "Pet Store API with Advanced Features",
        version = "1.0.0",
        extensions = {
            @Extension(name = "x-api-capabilities", properties = {
                @ExtensionProperty(name = "real-time", value = "webhooks,sse"),
                @ExtensionProperty(name = "batch-operations", value = "supported"),
                @ExtensionProperty(name = "async-processing", value = "callbacks")
            }),
            @Extension(name = "x-service-level", properties = {
                @ExtensionProperty(name = "availability", value = "99.9%"),
                @ExtensionProperty(name = "response-time-p95", value = "200ms"),
                @ExtensionProperty(name = "throughput", value = "1000-rps")
            })
        }
    ),
    extensions = {
        @Extension(name = "x-monetization", properties = {
            @ExtensionProperty(name = "pricing-model", value = "usage-based"),
            @ExtensionProperty(name = "billing-cycle", value = "monthly"),
            @ExtensionProperty(name = "free-tier", value = "1000-requests")
        }),
        @Extension(name = "x-compliance", properties = {
            @ExtensionProperty(name = "gdpr", value = "compliant"),
            @ExtensionProperty(name = "soc2", value = "type-2"),
            @ExtensionProperty(name = "pci-dss", value = "level-1")
        })
    }
)

Server Extensions

@Server(
    url = "https://api.petstore.io/v1",
    description = "Production server with enhanced features",
    extensions = {
        @Extension(name = "x-server-capabilities", properties = {
            @ExtensionProperty(name = "websockets", value = "supported"),
            @ExtensionProperty(name = "server-sent-events", value = "supported"),
            @ExtensionProperty(name = "graphql", value = "/graphql"),
            @ExtensionProperty(name = "grpc", value = "api.petstore.io:443")
        }),
        @Extension(name = "x-infrastructure", properties = {
            @ExtensionProperty(name = "provider", value = "aws"),
            @ExtensionProperty(name = "region", value = "us-east-1"),
            @ExtensionProperty(name = "load-balancer", value = "application"),
            @ExtensionProperty(name = "cdn", value = "cloudfront")
        })
    }
)

Callbacks

Define callback requests that your API will make to client-provided URLs, typically for asynchronous operations and event notifications.

Basic Callback Configuration

@PostMapping("/pets/{id}/process")
@Operation(
    summary = "Start pet processing",
    description = "Initiates asynchronous pet processing and calls back when complete",
    callbacks = @Callback(
        name = "processingComplete",
        callbackUrlExpression = "{$request.body#/callbackUrl}",
        operation = @Operation(
            method = "POST",
            summary = "Processing completion notification",
            requestBody = @RequestBody(
                description = "Processing results",
                content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = ProcessingResult.class)
                )
            ),
            responses = {
                @ApiResponse(
                    responseCode = "200",
                    description = "Callback received successfully"
                ),
                @ApiResponse(
                    responseCode = "400", 
                    description = "Invalid callback data"
                )
            }
        )
    )
)
public ResponseEntity<ProcessingRequest> startProcessing(
    @PathVariable Long id,
    @RequestBody ProcessingRequest request
) {
    // Start async processing
    ProcessingRequest response = petService.startProcessing(id, request);
    return ResponseEntity.accepted().body(response);
}

Multiple Callbacks with Different Events

@PostMapping("/orders")
@Operation(
    summary = "Create order with status notifications",
    callbacks = {
        @Callback(
            name = "orderStatusUpdate",
            callbackUrlExpression = "{$request.body#/webhooks.statusUpdate}",
            operation = @Operation(
                method = "POST",
                summary = "Order status change notification",
                requestBody = @RequestBody(
                    content = @Content(
                        mediaType = "application/json",
                        schema = @Schema(implementation = OrderStatusEvent.class)
                    )
                ),
                responses = @ApiResponse(responseCode = "200", description = "Status update received")
            )
        ),
        @Callback(
            name = "paymentProcessed",
            callbackUrlExpression = "{$request.body#/webhooks.payment}",
            operation = @Operation(
                method = "POST",
                summary = "Payment processing notification",
                requestBody = @RequestBody(
                    content = @Content(
                        mediaType = "application/json",
                        schema = @Schema(implementation = PaymentEvent.class)
                    )
                ),
                responses = @ApiResponse(responseCode = "200", description = "Payment notification received")
            )
        ),
        @Callback(
            name = "deliveryUpdate",
            callbackUrlExpression = "{$request.body#/webhooks.delivery}",
            operation = @Operation(
                method = "POST", 
                summary = "Delivery status notification",
                requestBody = @RequestBody(
                    content = @Content(
                        mediaType = "application/json",
                        schema = @Schema(implementation = DeliveryEvent.class)
                    )
                ),
                responses = @ApiResponse(responseCode = "200", description = "Delivery update received")
            )
        )
    }
)

Advanced Callback with Authentication

@PostMapping("/subscriptions")
@Operation(
    summary = "Create webhook subscription",
    callbacks = @Callback(
        name = "webhookEvent",
        callbackUrlExpression = "{$request.body#/targetUrl}",
        operation = @Operation(
            method = "POST",
            summary = "Webhook event notification",
            description = "Called when subscribed events occur",
            security = @SecurityRequirement(name = "webhook_signature"),
            parameters = {
                @Parameter(
                    name = "X-Webhook-Signature",
                    in = ParameterIn.HEADER,
                    description = "HMAC signature for webhook verification",
                    required = true,
                    schema = @Schema(type = "string")
                ),
                @Parameter(
                    name = "X-Event-Type", 
                    in = ParameterIn.HEADER,
                    description = "Type of event being delivered",
                    required = true,
                    schema = @Schema(type = "string", allowableValues = {
                        "pet.created", "pet.updated", "pet.deleted",
                        "order.placed", "order.shipped", "order.delivered"
                    })
                ),
                @Parameter(
                    name = "X-Delivery-ID",
                    in = ParameterIn.HEADER,
                    description = "Unique delivery attempt identifier",
                    required = true,
                    schema = @Schema(type = "string", format = "uuid")
                )
            },
            requestBody = @RequestBody(
                description = "Event payload",
                content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = WebhookEvent.class),
                    examples = {
                        @ExampleObject(
                            name = "petCreated",
                            summary = "Pet created event",
                            value = """
                                {
                                    "eventType": "pet.created",
                                    "timestamp": "2024-01-15T10:30:00Z",
                                    "data": {
                                        "id": 123,
                                        "name": "Fluffy",
                                        "status": "available"
                                    }
                                }
                                """
                        )
                    }
                )
            ),
            responses = {
                @ApiResponse(
                    responseCode = "200",
                    description = "Webhook processed successfully"
                ),
                @ApiResponse(
                    responseCode = "400",
                    description = "Invalid webhook payload"
                ),
                @ApiResponse(
                    responseCode = "401",
                    description = "Invalid webhook signature"
                )
            }
        )
    )
)

Webhooks

Document webhook endpoints that clients can implement to receive notifications from your API.

Basic Webhook Definition

@Webhook(
    name = "petUpdated",
    operation = @Operation(
        method = "POST",
        summary = "Pet update notification",
        description = "Called when a pet's information is updated",
        requestBody = @RequestBody(
            description = "Pet update event data",
            content = @Content(
                mediaType = "application/json",
                schema = @Schema(implementation = PetUpdateEvent.class)
            )
        ),
        responses = {
            @ApiResponse(responseCode = "200", description = "Webhook acknowledged"),
            @ApiResponse(responseCode = "410", description = "Webhook endpoint no longer exists")
        }
    )
)

Multiple Webhook Events

@Webhooks({
    @Webhook(
        name = "petLifecycle",
        operation = @Operation(
            summary = "Pet lifecycle events",
            description = "Notifications for pet creation, updates, and deletion",
            requestBody = @RequestBody(
                content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = PetLifecycleEvent.class),
                    examples = {
                        @ExampleObject(
                            name = "created",
                            summary = "Pet created",
                            value = """
                                {
                                    "event": "pet.created",
                                    "timestamp": "2024-01-15T10:30:00Z",
                                    "pet": {
                                        "id": 123,
                                        "name": "New Pet",
                                        "status": "available"
                                    }
                                }
                                """
                        ),
                        @ExampleObject(
                            name = "updated",
                            summary = "Pet updated", 
                            value = """
                                {
                                    "event": "pet.updated",
                                    "timestamp": "2024-01-15T10:35:00Z",
                                    "pet": {
                                        "id": 123,
                                        "name": "Updated Pet",
                                        "status": "sold"
                                    },
                                    "changes": ["name", "status"]
                                }
                                """
                        )
                    }
                )
            )
        )
    ),
    @Webhook(
        name = "orderStatus",
        operation = @Operation(
            summary = "Order status changes",
            description = "Notifications when order status changes",
            requestBody = @RequestBody(
                content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = OrderStatusEvent.class)
                )
            )
        )
    ),
    @Webhook(
        name = "inventoryAlert",
        operation = @Operation(
            summary = "Inventory level alerts", 
            description = "Notifications when inventory reaches threshold levels",
            requestBody = @RequestBody(
                content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = InventoryAlert.class)
                )
            )
        )
    )
})

Webhook with Security and Headers

@Webhook(
    name = "secureWebhook",
    operation = @Operation(
        summary = "Secure webhook with authentication",
        description = "Webhook with signature verification and custom headers",
        parameters = {
            @Parameter(
                name = "X-Webhook-Signature",
                in = ParameterIn.HEADER,
                required = true,
                description = "HMAC-SHA256 signature of the payload",
                schema = @Schema(type = "string"),
                example = "sha256=a8b7c6d5e4f3g2h1..."
            ),
            @Parameter(
                name = "X-Event-ID",
                in = ParameterIn.HEADER,
                required = true,
                description = "Unique event identifier for deduplication",
                schema = @Schema(type = "string", format = "uuid")
            ),
            @Parameter(
                name = "X-Retry-Count",
                in = ParameterIn.HEADER,
                required = false,
                description = "Number of delivery attempts (starts at 0)",
                schema = @Schema(type = "integer", minimum = "0", maximum = "5")
            )
        },
        requestBody = @RequestBody(
            description = "Signed webhook payload",
            content = @Content(
                mediaType = "application/json",
                schema = @Schema(implementation = SecureWebhookEvent.class)
            )
        ),
        responses = {
            @ApiResponse(
                responseCode = "200",
                description = "Webhook processed successfully"
            ),
            @ApiResponse(
                responseCode = "401",
                description = "Invalid signature",
                content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = WebhookError.class)
                )
            ),
            @ApiResponse(
                responseCode = "409",
                description = "Duplicate event (already processed)"
            ),
            @ApiResponse(
                responseCode = "422", 
                description = "Valid signature but invalid payload"
            )
        }
    )
)

Webhook Attributes

public @interface Webhook {
    String name();           // Required - Name of the webhook
    Operation operation();   // Required - Operation definition for the webhook
}

public @interface Webhooks {
    Webhook[] value() default {};  // Array of Webhook annotations
}

Links

Define relationships between operations, allowing clients to navigate from one operation's response to related operations.

Basic Operation Links

@PostMapping("/pets")
@ApiResponse(
    responseCode = "201",
    description = "Pet created successfully",
    content = @Content(
        mediaType = "application/json",
        schema = @Schema(implementation = Pet.class)
    ),
    links = {
        @Link(
            name = "GetPetById",
            description = "Retrieve the newly created pet",
            operationId = "getPetById",
            parameters = @LinkParameter(
                name = "id",
                expression = "$response.body#/id"
            )
        ),
        @Link(
            name = "UpdatePet",
            description = "Update the newly created pet",
            operationId = "updatePet",
            parameters = @LinkParameter(
                name = "id", 
                expression = "$response.body#/id"
            )
        ),
        @Link(
            name = "DeletePet",
            description = "Delete the newly created pet",
            operationId = "deletePet",
            parameters = @LinkParameter(
                name = "id",
                expression = "$response.body#/id"
            )
        )
    }
)
public ResponseEntity<Pet> createPet(@RequestBody Pet pet) {
    Pet createdPet = petService.create(pet);
    return ResponseEntity.status(HttpStatus.CREATED).body(createdPet);
}

Complex Links with Multiple Parameters

@GetMapping("/users/{userId}/pets")
@ApiResponse(
    responseCode = "200", 
    description = "User's pets retrieved",
    content = @Content(
        mediaType = "application/json",
        schema = @Schema(implementation = PetListResponse.class)
    ),
    links = {
        @Link(
            name = "GetUserProfile",
            description = "Get full user profile",
            operationId = "getUserById",
            parameters = @LinkParameter(
                name = "id",
                expression = "$request.path.userId"
            )
        ),
        @Link(
            name = "CreatePetForUser",
            description = "Create a new pet for this user",
            operationId = "createPetForUser", 
            parameters = {
                @LinkParameter(
                    name = "userId",
                    expression = "$request.path.userId"
                )
            }
        ),
        @Link(
            name = "GetPetDetails",
            description = "Get details for any pet in the list",
            operationId = "getPetById",
            parameters = @LinkParameter(
                name = "id",
                expression = "$response.body#/pets/*/id"
            )
        ),
        @Link(
            name = "GetUserOrders",
            description = "Get orders placed by this user",
            operationId = "getUserOrders",
            parameters = @LinkParameter(
                name = "userId",
                expression = "$request.path.userId"
            )
        )
    }
)

Conditional Links with Extensions

@GetMapping("/orders/{id}")
@ApiResponse(
    responseCode = "200",
    description = "Order details",
    content = @Content(
        mediaType = "application/json",
        schema = @Schema(implementation = Order.class)
    ),
    links = {
        @Link(
            name = "CancelOrder",
            description = "Cancel this order (if cancellable)",
            operationId = "cancelOrder",
            parameters = @LinkParameter(
                name = "id",
                expression = "$response.body#/id"
            ),
            extensions = {
                @Extension(name = "x-conditional", properties = {
                    @ExtensionProperty(name = "condition", value = "$response.body#/status == 'pending'"),
                    @ExtensionProperty(name = "description", value = "Only available for pending orders")
                })
            }
        ),
        @Link(
            name = "TrackShipment",
            description = "Track order shipment",
            operationId = "getShipmentTracking",
            parameters = @LinkParameter(
                name = "trackingNumber",
                expression = "$response.body#/trackingNumber"
            ),
            extensions = {
                @Extension(name = "x-conditional", properties = {
                    @ExtensionProperty(name = "condition", value = "$response.body#/status == 'shipped'"),
                    @ExtensionProperty(name = "description", value = "Only available for shipped orders")
                })
            }
        ),
        @Link(
            name = "RequestReturn",
            description = "Request return for delivered order",
            operationId = "createReturnRequest",
            parameters = @LinkParameter(
                name = "orderId",
                expression = "$response.body#/id"
            ),
            extensions = {
                @Extension(name = "x-conditional", properties = {
                    @ExtensionProperty(name = "condition", value = "$response.body#/status == 'delivered'"),
                    @ExtensionProperty(name = "timeLimit", value = "30 days from delivery")
                })
            }
        )
    }
)

OpenAPI 3.1 Features

Leverage enhanced OpenAPI 3.1 capabilities including improved JSON Schema support, conditional schemas, and enhanced validation.

OpenAPI 3.1 Marker Usage

@Schema(
    description = "Enhanced pet schema with OpenAPI 3.1 features",
    types = {"object", "null"},  // Multiple types
    $id = "https://api.petstore.io/schemas/pet.json",
    $schema = "https://json-schema.org/draft/2020-12/schema"
)
@OpenAPI31  // Marker for OpenAPI 3.1 specific features
public class EnhancedPet {
    
    @Schema(
        description = "Pet identifier with enhanced validation",
        types = {"integer", "string"},  // Can be either integer or string ID
        pattern = "^(\\d+|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})$"
    )
    @OpenAPI31
    private String id;
    
    @Schema(
        description = "Pet metadata with conditional requirements",
        _if = @Schema(
            properties = @SchemaProperty(
                name = "type",
                schema = @Schema(allowableValues = "premium")
            )
        ),
        _then = @Schema(
            required = {"certification", "insurance"},
            properties = {
                @SchemaProperty(
                    name = "certification",
                    schema = @Schema(type = "string", minLength = 1)
                ),
                @SchemaProperty(
                    name = "insurance",
                    schema = @Schema(type = "object", required = {"provider", "policyNumber"})
                )
            }
        )
    )
    @OpenAPI31
    private Map<String, Object> metadata;
    
    @Schema(
        description = "Pet images with enhanced array validation",
        prefixItems = {
            @Schema(description = "Primary image", format = "uri"),
            @Schema(description = "Thumbnail image", format = "uri")
        },
        minContains = 1,
        maxContains = 3,
        contains = @Schema(
            description = "Must contain at least one high-resolution image",
            properties = @SchemaProperty(
                name = "resolution",
                schema = @Schema(allowableValues = "high")
            )
        )
    )
    @OpenAPI31
    private List<PetImage> images;
}

Conditional Schema Validation

@Schema(
    description = "Payment method with conditional validation",
    discriminatorProperty = "type"
)
@OpenAPI31
public class PaymentMethod {
    
    @Schema(description = "Payment type")
    private String type;
    
    @Schema(
        description = "Payment details with type-specific validation",
        _if = @Schema(
            properties = @SchemaProperty(
                name = "type",
                schema = @Schema(allowableValues = "credit_card")
            )
        ),
        _then = @Schema(
            required = {"cardNumber", "expiryDate", "cvv"},
            properties = {
                @SchemaProperty(
                    name = "cardNumber", 
                    schema = @Schema(type = "string", pattern = "^[0-9]{13,19}$")
                ),
                @SchemaProperty(
                    name = "expiryDate",
                    schema = @Schema(type = "string", pattern = "^(0[1-9]|1[0-2])\\/[0-9]{2}$")
                ),
                @SchemaProperty(
                    name = "cvv",
                    schema = @Schema(type = "string", pattern = "^[0-9]{3,4}$")
                )
            }
        ),
        _else = @Schema(
            _if = @Schema(
                properties = @SchemaProperty(
                    name = "type",
                    schema = @Schema(allowableValues = "paypal")
                )
            ),
            _then = @Schema(
                required = {"paypalEmail"},
                properties = @SchemaProperty(
                    name = "paypalEmail",
                    schema = @Schema(type = "string", format = "email")
                )
            ),
            _else = @Schema(
                _if = @Schema(
                    properties = @SchemaProperty(
                        name = "type",
                        schema = @Schema(allowableValues = "bank_transfer")
                    )
                ),
                _then = @Schema(
                    required = {"accountNumber", "routingNumber"},
                    properties = {
                        @SchemaProperty(
                            name = "accountNumber",
                            schema = @Schema(type = "string", minLength = 8, maxLength = 17)
                        ),
                        @SchemaProperty(
                            name = "routingNumber", 
                            schema = @Schema(type = "string", pattern = "^[0-9]{9}$")
                        )
                    }
                )
            )
        )
    )
    @OpenAPI31
    private Map<String, Object> details;
}

Enhanced Composition with OpenAPI 3.1

@Content(
    mediaType = "application/json",
    oneOf = {
        @Schema(implementation = StandardUser.class),
        @Schema(implementation = PremiumUser.class), 
        @Schema(implementation = EnterpriseUser.class)
    },
    unevaluatedProperties = @Schema(
        description = "Additional properties not covered by oneOf schemas",
        additionalProperties = Schema.AdditionalPropertiesValue.FALSE
    )
)
@OpenAPI31
public class UserResponse {
    // Base user properties that apply to all user types
}

@Schema(
    description = "Dynamic configuration with pattern properties",
    patternProperties = {
        @PatternProperty(
            pattern = "^feature_[a-z]+$",
            schema = @Schema(
                type = "object",
                properties = {
                    @SchemaProperty(name = "enabled", schema = @Schema(type = "boolean")),
                    @SchemaProperty(name = "config", schema = @Schema(type = "object"))
                }
            )
        ),
        @PatternProperty(
            pattern = "^metric_[a-z_]+$",
            schema = @Schema(
                type = "number",
                minimum = "0"
            )
        )
    },
    unevaluatedProperties = @Schema(additionalProperties = Schema.AdditionalPropertiesValue.FALSE)
)
@OpenAPI31
public class DynamicConfiguration {
    // Static configuration properties
    @Schema(description = "Configuration version")
    private String version;
    
    @Schema(description = "Last updated timestamp")
    private Instant updatedAt;
    
    // Dynamic properties validated by pattern properties
}

Content Encoding and Media Type (OpenAPI 3.1)

@Schema(
    description = "File data with encoding information",
    contentEncoding = "base64",
    contentMediaType = "image/jpeg",
    type = "string"
)
@OpenAPI31
public class EncodedFileData {
    
    @Schema(
        description = "Base64 encoded image data",
        contentEncoding = "base64",
        contentMediaType = "image/jpeg"
    )
    private String imageData;
    
    @Schema(
        description = "Compressed text data", 
        contentEncoding = "gzip",
        contentMediaType = "text/plain"
    )
    private String compressedText;
    
    @Schema(
        description = "Binary file data",
        contentEncoding = "binary",
        contentMediaType = "application/octet-stream"
    )
    private String binaryData;
}

Complete Advanced Features Example

@RestController
@OpenAPIDefinition(
    info = @Info(
        title = "Advanced Pet Store API",
        version = "3.1.0",
        extensions = {
            @Extension(name = "x-api-features", properties = {
                @ExtensionProperty(name = "webhooks", value = "supported"),
                @ExtensionProperty(name = "callbacks", value = "supported"), 
                @ExtensionProperty(name = "openapi-version", value = "3.1")
            })
        }
    )
)
@Webhooks({
    @Webhook(
        name = "petStatusChanged",
        operation = @Operation(
            summary = "Pet status change notification",
            requestBody = @RequestBody(
                content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = PetStatusEvent.class)
                )
            )
        )
    )
})
public class AdvancedPetStoreController {
    
    @PostMapping("/pets/async-process")
    @Operation(
        summary = "Start asynchronous pet processing",
        extensions = {
            @Extension(name = "x-processing-type", properties = {
                @ExtensionProperty(name = "type", value = "asynchronous"),
                @ExtensionProperty(name = "estimated-duration", value = "5-10 minutes")
            })
        },
        callbacks = @Callback(
            name = "processingComplete",
            callbackUrlExpression = "{$request.body#/callbackUrl}",
            operation = @Operation(
                method = "POST",
                summary = "Processing completion callback",
                requestBody = @RequestBody(
                    content = @Content(
                        mediaType = "application/json",
                        schema = @Schema(implementation = ProcessingResult.class)
                    )
                )
            )
        )
    )
    @ApiResponse(
        responseCode = "202",
        description = "Processing started",
        content = @Content(
            schema = @Schema(implementation = ProcessingRequest.class)
        ),
        links = {
            @Link(
                name = "CheckStatus",
                operationId = "getProcessingStatus",
                parameters = @LinkParameter(
                    name = "processId",
                    expression = "$response.body#/processId"
                )
            ),
            @Link(
                name = "CancelProcessing",
                operationId = "cancelProcessing",
                parameters = @LinkParameter(
                    name = "processId", 
                    expression = "$response.body#/processId"
                )
            )
        }
    )
    public ResponseEntity<ProcessingRequest> startAsyncProcessing(
        @RequestBody @OpenAPI31 AsyncProcessingRequest request
    ) {
        ProcessingRequest result = petService.startAsyncProcessing(request);
        return ResponseEntity.accepted().body(result);
    }
}

Install with Tessl CLI

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

docs

advanced-features.md

core-annotations.md

index.md

responses.md

schema-media.md

security.md

servers-tags.md

tile.json