Jakarta EE compatible OpenAPI 3.x annotations for defining REST API specifications
—
Comprehensive schema definition system supporting OpenAPI 3.0 and 3.1 features including validation, composition, conditional schemas, and media type configuration. This system provides complete type definitions for request/response bodies, parameters, and data models.
Defines comprehensive schemas for OpenAPI elements with validation, typing, and composition features.
/**
* Defines schema for OpenAPI elements with extensive configuration
* Applied to: FIELD, METHOD, PARAMETER, TYPE, ANNOTATION_TYPE
*/
@Schema(
// Core schema properties
implementation = User.class, // Java class implementation
name = "UserSchema", // Schema name
title = "User Account", // Schema title
description = "User account information", // Schema description
// Composition schemas
not = RestrictedUser.class, // Disallowed properties class
oneOf = {BasicUser.class, PremiumUser.class}, // Exclusive match classes
anyOf = {User.class, AdminUser.class}, // Any match classes
allOf = {BaseUser.class, UserDetails.class}, // All match classes
// Type definitions
type = "object", // Schema type
types = {"object", "null"}, // Multiple schema types (OpenAPI 3.1)
format = "email", // Schema format
// Validation constraints
pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", // Regex pattern
multipleOf = 0.01, // Multiple constraint
maximum = "100", // Maximum value
exclusiveMaximum = true, // Exclusive maximum flag
exclusiveMaximumValue = 100.0, // Numeric exclusive maximum (OpenAPI 3.1)
minimum = "0", // Minimum value
exclusiveMinimum = false, // Exclusive minimum flag
exclusiveMinimumValue = 0.0, // Numeric exclusive minimum (OpenAPI 3.1)
maxLength = 255, // Maximum string length
minLength = 1, // Minimum string length
maxProperties = 50, // Maximum properties
minProperties = 1, // Minimum properties
// Property configuration
requiredProperties = {"email", "name"}, // Required properties
required = true, // Required flag (deprecated)
requiredMode = Schema.RequiredMode.REQUIRED, // Required mode
nullable = false, // Nullable flag
readOnly = false, // Read-only (deprecated)
writeOnly = false, // Write-only (deprecated)
accessMode = Schema.AccessMode.READ_WRITE, // Access mode
// Examples and defaults
example = "{\"name\":\"John\",\"email\":\"john@example.com\"}", // Example value
examples = {"example1", "example2"}, // Multiple example strings
exampleClasses = {UserExample1.class, UserExample2.class}, // Example classes
defaultValue = "{}", // Default value
_const = "constant_value", // Constant value (OpenAPI 3.1)
allowableValues = {"ACTIVE", "INACTIVE", "PENDING"}, // Enum values
// Property definitions
properties = { // Direct property definitions
@StringToClassMapItem(key = "userId", value = Long.class),
@StringToClassMapItem(key = "email", value = String.class)
},
additionalPropertiesSchema = @Schema(type = "string"), // Additional properties schema
patternProperties = { // Pattern-based properties
@StringToClassMapItem(key = "^config_.*", value = String.class)
},
propertyNames = @Schema(pattern = "^[a-zA-Z_][a-zA-Z0-9_]*$"), // Property names schema
// Array/object constraints
contains = User.class, // Contains constraint class
maxContains = 5, // Maximum contains matches
minContains = 1, // Minimum contains matches
prefixItems = {String.class, Integer.class}, // Tuple validation classes
additionalItems = @Schema(type = "boolean"), // Additional items schema
unevaluatedItems = @Schema(type = "string"), // Unevaluated items schema
// Conditional schemas (OpenAPI 3.1)
_if = ConditionSchema.class, // If condition schema
_else = ElseSchema.class, // Else condition schema
then = ThenSchema.class, // Then condition schema
// Dependent schemas and properties
dependentSchemas = { // Dependent schemas
@StringToClassMapItem(key = "paymentMethod", value = PaymentSchema.class)
},
dependentRequired = { // Dependent required properties
@DependentRequired(name = "billingAddress", value = {"street", "city"})
},
// Advanced features
discriminatorProperty = "type", // Discriminator property
discriminatorMapping = { // Discriminator mappings
@DiscriminatorMapping(value = "user", schema = User.class),
@DiscriminatorMapping(value = "admin", schema = AdminUser.class)
},
subTypes = {User.class, AdminUser.class}, // Subtype classes
schemaResolution = Schema.SchemaResolution.INLINE, // Schema resolution strategy
// Content properties (OpenAPI 3.1)
contentEncoding = "base64", // Content encoding
contentMediaType = "application/json", // Content media type
contentSchema = ContentDataSchema.class, // Content schema
// OpenAPI 3.1 identifiers
$id = "https://example.com/schemas/user", // Schema identifier
$schema = "https://json-schema.org/draft/2020-12/schema", // JSON Schema dialect
$anchor = "user-schema", // Schema anchor
$vocabulary = "https://example.com/vocabulary", // Schema vocabulary
$dynamicAnchor = "user-anchor", // Dynamic anchor
$comment = "User schema with validation", // Schema comment
// Metadata
deprecated = false, // Deprecated flag
hidden = false, // Hidden flag
enumAsRef = false, // Enum as reference
extensions = {@Extension(...)}, // Custom extensions
externalDocs = @ExternalDocumentation(...), // External documentation
ref = "#/components/schemas/User" // Schema reference
)Schema Internal Enums:
enum Schema.AccessMode {
AUTO, // Determine automatically
READ_ONLY, // Read-only access
WRITE_ONLY, // Write-only access
READ_WRITE // Full read-write access
}
enum Schema.RequiredMode {
AUTO, // Determine automatically
REQUIRED, // Property is required
NOT_REQUIRED // Property is optional
}
enum Schema.AdditionalPropertiesValue {
TRUE, // Allow additional properties
FALSE, // Disallow additional properties
USE_ADDITIONAL_PROPERTIES_ANNOTATION // Use annotation-based detection
}
enum Schema.SchemaResolution {
AUTO, // Automatic resolution
DEFAULT, // Default resolution
INLINE, // Inline schema
ALL_OF, // AllOf composition
ALL_OF_REF // AllOf with references
}Usage Examples:
// Basic schema on class
@Schema(description = "User account information")
public class User {
@Schema(description = "Unique identifier", example = "123", accessMode = Schema.AccessMode.READ_ONLY)
private Long id;
@Schema(
description = "Email address",
format = "email",
pattern = "^[^@]+@[^@]+\\.[^@]+$",
example = "user@example.com"
)
private String email;
@Schema(description = "User status", allowableValues = {"ACTIVE", "INACTIVE", "SUSPENDED"})
private UserStatus status;
}
// Composition schemas
@Schema(
description = "Premium user with extended features",
allOf = {User.class, PremiumFeatures.class}
)
public class PremiumUser {}
// Polymorphic schemas with discriminator
@Schema(
description = "Base account type",
discriminatorProperty = "accountType",
discriminatorMapping = {
@DiscriminatorMapping(value = "personal", schema = PersonalAccount.class),
@DiscriminatorMapping(value = "business", schema = BusinessAccount.class)
},
subTypes = {PersonalAccount.class, BusinessAccount.class}
)
public abstract class Account {
@Schema(description = "Account type discriminator")
private String accountType;
}
// Validation constraints
@Schema(
description = "Product price",
type = "number",
format = "decimal",
minimum = "0.01",
maximum = "99999.99",
multipleOf = 0.01,
example = "29.99"
)
private BigDecimal price;Defines schemas specifically for array types with additional array-specific constraints.
/**
* Defines array schema with array-specific properties
* Applied to: FIELD, METHOD, PARAMETER, TYPE, ANNOTATION_TYPE
*/
@ArraySchema(
schema = @Schema(implementation = String.class), // Schema of array items
arraySchema = @Schema( // Properties of array itself
description = "List of user IDs",
example = "[\"123\", \"456\", \"789\"]"
),
minItems = 1, // Minimum array length
maxItems = 100, // Maximum array length
uniqueItems = true, // Items must be unique
extensions = {@Extension(...)}, // Custom extensions
// OpenAPI 3.1 array features
contains = @Schema(type = "string"), // Contains constraint
maxContains = 5, // Maximum contains matches
minContains = 1, // Minimum contains matches
unevaluatedItems = @Schema(type = "boolean"), // Unevaluated items schema
prefixItems = { // Tuple validation
@Schema(type = "string"),
@Schema(type = "integer")
}
)Usage Examples:
// String array with constraints
@ArraySchema(
schema = @Schema(type = "string", minLength = 1),
minItems = 1,
maxItems = 5,
uniqueItems = true
)
private List<String> tags;
// Object array
@ArraySchema(
schema = @Schema(implementation = User.class),
minItems = 0,
maxItems = 100
)
private List<User> users;
// Tuple-like array (OpenAPI 3.1)
@ArraySchema(
prefixItems = {
@Schema(type = "string", description = "Name"),
@Schema(type = "integer", description = "Age"),
@Schema(type = "string", description = "Email")
},
minItems = 3,
maxItems = 3
)
private List<Object> userTuple;Defines content/media types for parameters, request bodies, and responses with schema and examples.
/**
* Defines content for different media types
* Applied to: within other annotations
*/
@Content(
mediaType = "application/json", // Media type (required)
schema = @Schema(implementation = User.class), // Content schema
schemaProperties = @SchemaProperties(...), // Schema properties
additionalPropertiesSchema = @Schema(...), // Additional properties schema
additionalPropertiesArraySchema = @ArraySchema(...), // Additional properties array
array = @ArraySchema(...), // Array schema alternative
examples = { // Multiple examples
@ExampleObject(name = "user1", value = "{}"),
@ExampleObject(name = "user2", ref = "#/components/examples/User2")
},
encoding = {@Encoding(...)}, // Encoding configurations
extensions = {@Extension(...)}, // Custom extensions
// OpenAPI 3.1 content features
dependentSchemas = @DependentSchemas(...), // Dependent schemas
dependentRequired = @DependentRequiredMap(...), // Dependent required properties
patternProperties = @PatternProperties(...), // Pattern properties
properties = @SchemaProperties(...), // Property definitions
unevaluatedProperties = @Schema(...) // Unevaluated properties schema
)Usage Examples:
// JSON content with schema
@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",
externalValue = "https://example.com/examples/admin-user.json"
)
}
)
// Multiple content types
@ApiResponse(
responseCode = "200",
content = {
@Content(
mediaType = "application/json",
schema = @Schema(implementation = User.class)
),
@Content(
mediaType = "application/xml",
schema = @Schema(implementation = User.class)
),
@Content(
mediaType = "text/plain",
schema = @Schema(type = "string")
)
}
)
// File upload content
@Content(
mediaType = "multipart/form-data",
encoding = {
@Encoding(
name = "file",
contentType = "application/octet-stream",
style = "form",
explode = false
),
@Encoding(
name = "metadata",
contentType = "application/json"
)
}
)Defines examples for schemas, parameters, and content with metadata and references.
/**
* Defines examples with metadata
* Applied to: within other annotations
*/
@ExampleObject(
name = "userExample", // Example name
summary = "Basic user example", // Short summary
description = "Example of a basic user object", // Detailed description
value = "{\"id\":123,\"name\":\"John Doe\"}", // Inline example value
externalValue = "https://example.com/user.json", // External example URL
extensions = {@Extension(...)}, // Custom extensions
ref = "#/components/examples/BasicUser" // Reference to component example
)Defines individual properties within schemas, useful for complex object definitions.
/**
* Container for schema property definitions
*/
@SchemaProperties({
@SchemaProperty(
name = "userId",
schema = @Schema(type = "integer", format = "int64", description = "User ID")
),
@SchemaProperty(
name = "email",
schema = @Schema(type = "string", format = "email", description = "Email address")
)
})
/**
* Individual schema property definition
* Repeatable: Yes
*/
@SchemaProperty(
name = "propertyName", // Property name
schema = @Schema(...), // Property schema
array = @ArraySchema(...) // Array schema alternative
)Maps discriminator values to specific schemas for polymorphic types.
/**
* Maps discriminator values to schemas
*/
@DiscriminatorMapping(
value = "premium", // Discriminator value
schema = PremiumUser.class, // Schema class for this value
extensions = {@Extension(...)} // Custom extensions (OpenAPI 3.1)
)Defines encoding for multipart and form data submissions.
/**
* Defines encoding for request body properties
*/
@Encoding(
name = "profileImage", // Property name
contentType = "image/png, image/jpeg", // Allowed content types
style = "form", // Encoding style
explode = true, // Explode objects/arrays
allowReserved = false, // Allow reserved characters
headers = { // Additional headers
@Header(name = "X-File-Type", schema = @Schema(type = "string"))
},
extensions = {@Extension(...)} // Custom extensions
)Usage Example:
@RequestBody(
content = @Content(
mediaType = "multipart/form-data",
encoding = {
@Encoding(
name = "document",
contentType = "application/pdf, application/msword",
headers = @Header(
name = "X-Document-Type",
schema = @Schema(type = "string", allowableValues = {"pdf", "doc", "docx"})
)
),
@Encoding(
name = "metadata",
contentType = "application/json",
style = "form",
explode = false
)
}
)
)Defines schemas that depend on the presence of other properties.
/**
* Container for dependent schema definitions (OpenAPI 3.1)
*/
@DependentSchemas({
@DependentSchema(
name = "billingAddress",
schema = @Schema(
description = "Required when payment method is credit card",
required = true,
properties = @SchemaProperties({
@SchemaProperty(name = "street", schema = @Schema(type = "string")),
@SchemaProperty(name = "city", schema = @Schema(type = "string"))
})
)
)
})
/**
* Individual dependent schema (OpenAPI 3.1)
* Repeatable: Yes
*/
@DependentSchema(
name = "dependentProperty", // Property name
schema = @Schema(...), // Dependent schema
array = @ArraySchema(...) // Array schema alternative
)Defines properties that become required based on other properties.
/**
* Container for dependent required properties (OpenAPI 3.1)
*/
@DependentRequiredMap({
@DependentRequired(
name = "paymentMethod", // Trigger property
value = {"cardNumber", "expiryDate", "cvv"} // Required when trigger present
),
@DependentRequired(
name = "shippingMethod",
value = {"shippingAddress"}
)
})
/**
* Individual dependent required definition (OpenAPI 3.1)
* Repeatable: Yes
*/
@DependentRequired(
name = "triggerProperty", // Property that triggers requirement
value = {"required1", "required2"} // Properties that become required
)Defines schemas for properties matching regex patterns.
/**
* Container for pattern property definitions (OpenAPI 3.1)
*/
@PatternProperties({
@PatternProperty(
regex = "^[a-zA-Z]+$",
schema = @Schema(type = "string", description = "Alphabetic properties")
),
@PatternProperty(
regex = "^\\d+$",
schema = @Schema(type = "integer", description = "Numeric properties")
)
})
/**
* Individual pattern property definition (OpenAPI 3.1)
* Repeatable: Yes
*/
@PatternProperty(
regex = "^prefix_.+", // Regular expression pattern
schema = @Schema(...) // Schema for matching properties
)Usage Example:
@Schema(
description = "Dynamic configuration object",
patternProperties = @PatternProperties({
@PatternProperty(
regex = "^config_[a-zA-Z]+$",
schema = @Schema(type = "string", description = "Configuration values")
),
@PatternProperty(
regex = "^feature_[a-zA-Z]+$",
schema = @Schema(type = "boolean", description = "Feature flags")
)
})
)
public class DynamicConfig {
// Properties matching patterns will be validated accordingly
// e.g., config_database="localhost", feature_newUI=true
}@Schema(
description = "Extended user with admin privileges",
allOf = {User.class, AdminPrivileges.class}
)
public class AdminUser {}@Schema(
description = "Payment method - either card or bank transfer",
oneOf = {CreditCard.class, BankTransfer.class},
discriminatorProperty = "type"
)
public abstract class PaymentMethod {}@Schema(
description = "User with optional contact preferences",
anyOf = {BasicUser.class, ContactPreferences.class}
)
public class FlexibleUser {}Install with Tessl CLI
npx tessl i tessl/maven-io-swagger-core-v3--swagger-annotations-jakarta