Swagger Core annotations library providing OpenAPI 3.x annotations for Java applications, enabling developers to document REST APIs with metadata annotations
—
This document covers annotations for defining data schemas, array schemas, content types, examples, and encoding specifications for OpenAPI documentation.
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Encoding;
import io.swagger.v3.oas.annotations.media.DiscriminatorMapping;
import io.swagger.v3.oas.annotations.media.SchemaProperty;
import io.swagger.v3.oas.annotations.media.SchemaProperties;
import io.swagger.v3.oas.annotations.media.DependentRequired;
import io.swagger.v3.oas.annotations.media.DependentSchema;
import io.swagger.v3.oas.annotations.media.PatternProperty;
import io.swagger.v3.oas.annotations.media.PatternProperties;
import io.swagger.v3.oas.annotations.media.DependentRequiredMap;
import io.swagger.v3.oas.annotations.media.DependentSchemas;Defines comprehensive schemas for OpenAPI elements with extensive validation properties, type definitions, and OpenAPI 3.1 enhanced features.
@Schema(
name = "Pet",
description = "Pet information model with comprehensive validation",
title = "Pet",
type = "object",
requiredProperties = {"name", "status"},
example = "{ \"id\": 1, \"name\": \"Fluffy\", \"category\": { \"id\": 1, \"name\": \"Dogs\" }, \"status\": \"available\" }"
)
public class Pet {
@Schema(
description = "Pet identifier",
example = "123",
accessMode = Schema.AccessMode.READ_ONLY,
type = "integer",
format = "int64"
)
private Long id;
@Schema(
description = "Pet name",
example = "Fluffy",
minLength = 1,
maxLength = 50,
pattern = "^[a-zA-Z0-9\\s]+$",
nullable = false
)
private String name;
@Schema(
description = "Pet category information",
implementation = Category.class,
nullable = true
)
private Category category;
@Schema(
description = "Pet status in the store",
allowableValues = {"available", "pending", "sold"},
defaultValue = "available",
example = "available"
)
private String status;
@Schema(
description = "Pet price",
type = "number",
format = "decimal",
minimum = "0",
maximum = "10000",
multipleOf = 0.01,
exclusiveMinimum = true
)
private BigDecimal price;
}@Schema(
description = "Advanced pet model with complex validation",
minProperties = 2,
maxProperties = 20,
additionalProperties = Schema.AdditionalPropertiesValue.FALSE,
discriminatorProperty = "type",
discriminatorMapping = {
@DiscriminatorMapping(value = "dog", schema = Dog.class),
@DiscriminatorMapping(value = "cat", schema = Cat.class)
},
subTypes = {Dog.class, Cat.class}
)
public abstract class Pet {
@Schema(description = "Pet type discriminator", required = true)
protected String type;
@Schema(
description = "Pet tags",
uniqueItems = true,
maxItems = 10,
minItems = 0
)
private Set<String> tags;
}// OneOf Schema
@Schema(
description = "Payment method",
oneOf = {CreditCard.class, PayPal.class, BankTransfer.class},
discriminatorProperty = "type"
)
public abstract class PaymentMethod {
protected String type;
}
// AllOf Schema
@Schema(
description = "Enhanced pet with location",
allOf = {Pet.class, Location.class}
)
public class EnhancedPet {
// Inherits all properties from Pet and Location
}
// AnyOf Schema
@Schema(
description = "Contact information",
anyOf = {EmailContact.class, PhoneContact.class, Address.class}
)
public class Contact {
// Can be validated against any of the specified schemas
}
// Not Schema
@Schema(
description = "Valid pet data",
not = InvalidPet.class,
implementation = Pet.class
)
public class ValidPet extends Pet {
// Must not match InvalidPet schema
}@Schema(
description = "OpenAPI 3.1 enhanced schema",
types = {"object", "null"}, // Multiple types
$id = "https://example.com/pet.json", // Schema ID
$schema = "https://json-schema.org/draft/2020-12/schema", // Schema dialect
$anchor = "pet", // Schema anchor
contentEncoding = "base64", // Content encoding
contentMediaType = "image/png", // Content media type
exclusiveMaximumValue = 100, // Numeric exclusive maximum
exclusiveMinimumValue = 0 // Numeric exclusive minimum
)
public class EnhancedPetSchema {
@Schema(description = "Pet image data", contentEncoding = "base64")
private String imageData;
}public @interface Schema {
// Core properties
Class<?> implementation() default Void.class;
Class<?> not() default Void.class;
Class<?>[] oneOf() default {};
Class<?>[] anyOf() default {};
Class<?>[] allOf() default {};
String name() default "";
String title() default "";
String description() default "";
// Type and format
String type() default "";
String format() default "";
String[] types() default {}; // OpenAPI 3.1
// Validation constraints
boolean nullable() default false;
boolean deprecated() default false;
double multipleOf() default 0;
String maximum() default "";
boolean exclusiveMaximum() default false;
String minimum() default "";
boolean exclusiveMinimum() default false;
int maxLength() default Integer.MAX_VALUE;
int minLength() default 0;
String pattern() default "";
int maxProperties() default 0;
int minProperties() default 0;
String[] requiredProperties() default {};
@Deprecated
boolean required() default false; // Deprecated since 2.2.5, use requiredMode
// Enum and examples
String[] allowableValues() default {};
String defaultValue() default "";
String example() default "";
// OpenAPI 3.1 specific
int exclusiveMaximumValue() default 0;
int exclusiveMinimumValue() default 0;
String $id() default "";
String $schema() default "";
String $anchor() default "";
String $vocabulary() default ""; // OpenAPI 3.1
String $dynamicAnchor() default ""; // OpenAPI 3.1
String $comment() default ""; // OpenAPI 3.1
String contentEncoding() default "";
String contentMediaType() default "";
// Access control
AccessMode accessMode() default AccessMode.AUTO;
RequiredMode requiredMode() default RequiredMode.AUTO;
// Schema resolution control
SchemaResolution schemaResolution() default SchemaResolution.AUTO;
// OpenAPI 3.1 conditional schemas
Class<?> _if() default Void.class;
Class<?> _then() default Void.class;
Class<?> _else() default Void.class;
Class<?> then() default Void.class; // Alternative to _then
// Additional properties and extensions
AdditionalPropertiesValue additionalProperties() default AdditionalPropertiesValue.USE_ADDITIONAL_PROPERTIES_ANNOTATION;
Extension[] extensions() default {};
// Enums
enum AccessMode { READ_ONLY, WRITE_ONLY, READ_WRITE, AUTO }
enum AdditionalPropertiesValue { TRUE, FALSE, USE_ADDITIONAL_PROPERTIES_ANNOTATION }
enum RequiredMode { AUTO, REQUIRED, NOT_REQUIRED }
enum SchemaResolution { AUTO, DEFAULT, INLINE, ALL_OF, ALL_OF_REF }
}Defines schemas specifically for array types with comprehensive array-specific validation and OpenAPI 3.1 enhanced features.
@ArraySchema(
schema = @Schema(implementation = Pet.class),
arraySchema = @Schema(
description = "List of pets in the store",
example = "[{\"id\": 1, \"name\": \"Fluffy\"}, {\"id\": 2, \"name\": \"Buddy\"}]"
),
minItems = 0,
maxItems = 100,
uniqueItems = true
)
private List<Pet> pets;
// Multi-dimensional arrays
@ArraySchema(
schema = @ArraySchema(
schema = @Schema(type = "integer"),
arraySchema = @Schema(description = "Row of integers")
),
arraySchema = @Schema(description = "Matrix of integers"),
minItems = 1,
maxItems = 10
)
private List<List<Integer>> matrix;@ArraySchema(
schema = @Schema(implementation = Pet.class),
arraySchema = @Schema(description = "Enhanced pet list with 3.1 features"),
// OpenAPI 3.1 specific properties
contains = @Schema(
description = "At least one pet must match this schema",
properties = {
@SchemaProperty(name = "featured", schema = @Schema(type = "boolean", allowableValues = "true"))
}
),
minContains = 1,
maxContains = 5,
// Prefix items for tuple validation
prefixItems = {
@Schema(description = "First pet (must be featured)", implementation = FeaturedPet.class),
@Schema(description = "Second pet (any type)", implementation = Pet.class)
},
unevaluatedItems = @Schema(
description = "Additional pets beyond prefix items",
implementation = StandardPet.class
)
)
private List<Pet> enhancedPetList;public @interface ArraySchema {
Schema schema() default @Schema;
Schema arraySchema() default @Schema;
int maxItems() default Integer.MIN_VALUE;
int minItems() default Integer.MAX_VALUE;
boolean uniqueItems() default false;
Extension[] extensions() default {};
// OpenAPI 3.1 features
Schema contains() default @Schema;
int maxContains() default 0;
int minContains() default 0;
Schema unevaluatedItems() default @Schema;
Schema[] prefixItems() default {};
}Defines content and media types for parameters, request bodies, or responses with comprehensive schema and example definitions.
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Pet.class),
examples = {
@ExampleObject(
name = "petExample",
summary = "Example pet",
description = "A complete example of a pet object",
value = "{ \"id\": 1, \"name\": \"Fluffy\", \"category\": { \"id\": 1, \"name\": \"Dogs\" }, \"status\": \"available\" }"
),
@ExampleObject(
name = "minimalPet",
summary = "Minimal pet example",
value = "{ \"name\": \"Buddy\", \"status\": \"available\" }"
)
}
)
// Multiple content types
@Content(mediaType = "application/json", schema = @Schema(implementation = Pet.class))
@Content(mediaType = "application/xml", schema = @Schema(implementation = Pet.class))
@Content(mediaType = "text/plain", schema = @Schema(type = "string"))@Content(
mediaType = "application/json",
schemaProperties = {
@SchemaProperty(
name = "pet",
schema = @Schema(implementation = Pet.class)
),
@SchemaProperty(
name = "metadata",
schema = @Schema(
type = "object",
description = "Additional metadata"
)
),
@SchemaProperty(
name = "tags",
array = @ArraySchema(
schema = @Schema(type = "string"),
minItems = 0,
maxItems = 10
)
)
}
)@Content(
mediaType = "multipart/form-data",
schema = @Schema(implementation = PetUploadRequest.class),
encoding = {
@Encoding(
name = "petData",
contentType = "application/json",
style = "form",
explode = true,
headers = {
@Header(
name = "X-Pet-Version",
description = "Pet data format version",
schema = @Schema(type = "string", defaultValue = "1.0")
)
}
),
@Encoding(
name = "image",
contentType = "image/jpeg, image/png",
headers = {
@Header(
name = "Content-Disposition",
schema = @Schema(type = "string", defaultValue = "form-data")
)
}
)
}
)@Content(
mediaType = "application/json",
// OpenAPI 3.1 conditional schemas
dependentSchemas = {
@DependentSchema(
name = "petType",
schema = @Schema(
_if = @Schema(properties = {
@SchemaProperty(name = "type", schema = @Schema(allowableValues = "dog"))
}),
_then = @Schema(properties = {
@SchemaProperty(name = "breed", schema = @Schema(type = "string", required = true))
}),
_else = @Schema(properties = {
@SchemaProperty(name = "species", schema = @Schema(type = "string", required = true))
})
)
)
},
contentSchema = @Schema(implementation = Pet.class),
propertyNames = @Schema(pattern = "^[a-zA-Z_][a-zA-Z0-9_]*$"),
// Composition schemas in content
oneOf = {
@Schema(implementation = Dog.class),
@Schema(implementation = Cat.class),
@Schema(implementation = Bird.class)
},
anyOf = {
@Schema(implementation = Pet.class),
@Schema(implementation = Toy.class)
},
allOf = {
@Schema(implementation = Animal.class),
@Schema(implementation = Domesticated.class)
}
)public @interface Content {
String mediaType() default "";
ExampleObject[] examples() default {};
Schema schema() default @Schema();
SchemaProperty[] schemaProperties() default {};
Schema additionalPropertiesSchema() default @Schema();
ArraySchema additionalPropertiesArraySchema() default @ArraySchema();
ArraySchema array() default @ArraySchema();
Encoding[] encoding() default {};
Extension[] extensions() default {};
// OpenAPI 3.1 features
DependentSchema[] dependentSchemas() default {};
Schema contentSchema() default @Schema();
Schema propertyNames() default @Schema();
Schema _if() default @Schema();
Schema _then() default @Schema();
Schema _else() default @Schema();
Schema not() default @Schema();
Schema[] oneOf() default {};
Schema[] anyOf() default {};
Schema[] allOf() default {};
}Provides comprehensive examples for parameters, request bodies, and response content with support for external references and extensions.
@ExampleObject(
name = "createPetExample",
summary = "Create a new pet",
description = "Example showing how to create a new pet with all required fields",
value = """
{
"name": "Fluffy",
"category": {
"id": 1,
"name": "Dogs"
},
"status": "available",
"tags": ["friendly", "trained"],
"photoUrls": ["https://example.com/photos/fluffy1.jpg"]
}
"""
)
@ExampleObject(
name = "updatePetExample",
summary = "Update existing pet",
description = "Example showing partial update of pet information",
value = """
{
"name": "Fluffy Updated",
"status": "sold"
}
"""
)
// External example reference
@ExampleObject(
name = "complexPetExample",
summary = "Complex pet with all fields",
externalValue = "https://api.petstore.io/examples/complex-pet.json",
description = "Comprehensive example hosted externally"
)@Content(
mediaType = "application/json",
schema = @Schema(implementation = Pet.class),
examples = {
@ExampleObject(
name = "dog",
summary = "Dog example",
description = "Example of a dog pet",
value = """
{
"id": 1,
"name": "Buddy",
"category": {"id": 1, "name": "Dogs"},
"breed": "Golden Retriever",
"status": "available"
}
"""
),
@ExampleObject(
name = "cat",
summary = "Cat example",
description = "Example of a cat pet",
value = """
{
"id": 2,
"name": "Whiskers",
"category": {"id": 2, "name": "Cats"},
"indoor": true,
"status": "available"
}
"""
),
@ExampleObject(
name = "errorExample",
summary = "Error response example",
description = "Example error when pet not found",
value = """
{
"error": "Pet not found",
"code": 404,
"message": "No pet exists with the provided ID"
}
"""
)
}
)public @interface ExampleObject {
String name() default "";
String summary() default "";
String value() default "";
String externalValue() default "";
Extension[] extensions() default {};
String ref() default "";
String description() default "";
}Defines encoding details for multipart and form data content types, including headers and serialization options.
@Content(
mediaType = "multipart/form-data",
schema = @Schema(implementation = PetUploadForm.class),
encoding = {
@Encoding(
name = "petJson",
contentType = "application/json",
style = "form",
explode = true,
allowReserved = false,
headers = {
@Header(
name = "X-Pet-Format-Version",
description = "Version of the pet JSON format",
schema = @Schema(type = "string", defaultValue = "2.0")
)
}
),
@Encoding(
name = "photos",
contentType = "image/jpeg, image/png, image/gif",
style = "form",
explode = true,
headers = {
@Header(
name = "Content-Disposition",
description = "File disposition header",
schema = @Schema(type = "string")
),
@Header(
name = "X-Image-Quality",
description = "Image quality indicator",
schema = @Schema(type = "string", allowableValues = {"low", "medium", "high"})
)
}
),
@Encoding(
name = "metadata",
contentType = "application/json",
style = "deepObject",
explode = true
)
}
)@Content(
mediaType = "application/x-www-form-urlencoded",
schema = @Schema(implementation = SearchForm.class),
encoding = {
@Encoding(
name = "categories",
style = "form",
explode = true,
allowReserved = false
),
@Encoding(
name = "dateRange",
style = "deepObject",
explode = true
)
}
)public @interface Encoding {
String name() default "";
String contentType() default "";
String style() default "";
boolean explode() default false;
boolean allowReserved() default false;
Header[] headers() default {};
Extension[] extensions() default {};
}Define individual properties for object schemas with detailed configurations.
@SchemaProperties({
@SchemaProperty(
name = "id",
schema = @Schema(
type = "integer",
format = "int64",
description = "Pet identifier",
minimum = "1"
)
),
@SchemaProperty(
name = "name",
schema = @Schema(
type = "string",
description = "Pet name",
minLength = 1,
maxLength = 50,
pattern = "^[a-zA-Z0-9\\s]+$"
)
),
@SchemaProperty(
name = "categories",
array = @ArraySchema(
schema = @Schema(implementation = Category.class),
minItems = 0,
maxItems = 5,
uniqueItems = true
)
)
})Define conditional required fields based on the presence of other fields.
@DependentRequired(name = "creditCard", value = {"cardNumber", "expiryDate", "cvv"})
@DependentRequired(name = "paypal", value = {"paypalEmail"})
@DependentRequired(name = "bankTransfer", value = {"accountNumber", "routingNumber"})
@Schema(description = "Payment information with dependent requirements")
public class PaymentInfo {
private String paymentMethod; // "creditCard", "paypal", "bankTransfer"
private String cardNumber;
private String expiryDate;
private String cvv;
private String paypalEmail;
private String accountNumber;
private String routingNumber;
}Define conditional schemas that apply when certain conditions are met.
@Content(
mediaType = "application/json",
dependentSchemas = {
@DependentSchema(
name = "petType",
schema = @Schema(
// If pet type is "dog", then breed is required
_if = @Schema(
properties = @SchemaProperty(
name = "type",
schema = @Schema(allowableValues = "dog")
)
),
_then = @Schema(
properties = @SchemaProperty(
name = "breed",
schema = @Schema(type = "string", required = true)
)
),
// If pet type is "cat", then indoor status is required
_else = @Schema(
_if = @Schema(
properties = @SchemaProperty(
name = "type",
schema = @Schema(allowableValues = "cat")
)
),
_then = @Schema(
properties = @SchemaProperty(
name = "indoor",
schema = @Schema(type = "boolean", required = true)
)
)
)
)
)
}
)Define mappings for polymorphic schemas using discriminator properties.
@Schema(
description = "Base animal class with discriminator",
discriminatorProperty = "animalType",
discriminatorMapping = {
@DiscriminatorMapping(value = "dog", schema = Dog.class),
@DiscriminatorMapping(value = "cat", schema = Cat.class),
@DiscriminatorMapping(value = "bird", schema = Bird.class)
},
oneOf = {Dog.class, Cat.class, Bird.class}
)
public abstract class Animal {
@Schema(description = "Type of animal", required = true)
protected String animalType;
@Schema(description = "Animal name", required = true)
protected String name;
}
@Schema(description = "Dog specific properties")
public class Dog extends Animal {
@Schema(description = "Dog breed")
private String breed;
@Schema(description = "Is house trained")
private Boolean houseTrained;
public Dog() {
this.animalType = "dog";
}
}Define schema properties based on property name patterns.
@PatternProperty(
pattern = "^[a-zA-Z]+_[0-9]+$",
schema = @Schema(
type = "object",
description = "Properties matching pattern prefix_number",
properties = {
@SchemaProperty(name = "value", schema = @Schema(type = "string")),
@SchemaProperty(name = "type", schema = @Schema(type = "string"))
}
)
)
@PatternProperty(
pattern = "^temp_.*",
schema = @Schema(
type = "string",
description = "Temporary properties (strings only)"
)
)
@Schema(description = "Dynamic properties with pattern-based validation")
public class DynamicConfig {
// Static properties
@Schema(description = "Configuration name")
private String name;
// Dynamic properties will be validated against patterns
// Examples: config_1, config_2 (matches first pattern)
// temp_data, temp_cache (matches second pattern)
}OpenAPI 3.1 introduces conditional validation through dependent required fields and dependent schemas.
Define conditional required fields based on the presence of other fields.
@Schema(description = "Payment information with conditional requirements")
public class PaymentInfo {
@Schema(description = "Payment method type")
private String paymentMethod; // "creditCard", "paypal", "bankTransfer"
// These fields are required only if paymentMethod is "creditCard"
@DependentRequired(name = "creditCard", value = {"cardNumber", "expiryDate", "cvv"})
private String cardNumber;
@DependentRequired(name = "creditCard", value = {"cardNumber", "expiryDate", "cvv"})
private String expiryDate;
@DependentRequired(name = "creditCard", value = {"cardNumber", "expiryDate", "cvv"})
private String cvv;
// Required only if paymentMethod is "paypal"
@DependentRequired(name = "paypal", value = {"paypalEmail"})
private String paypalEmail;
// Required only if paymentMethod is "bankTransfer"
@DependentRequired(name = "bankTransfer", value = {"accountNumber", "routingNumber"})
private String accountNumber;
@DependentRequired(name = "bankTransfer", value = {"accountNumber", "routingNumber"})
private String routingNumber;
}Define conditional schemas that apply when certain conditions are met.
@Schema(
description = "Pet with type-dependent validation",
dependentSchemas = {
@StringToClassMapItem(key = "petType", value = PetTypeSchema.class)
}
)
public class ConditionalPet {
@Schema(description = "Pet type", allowableValues = {"dog", "cat", "bird"})
private String type;
@Schema(description = "Pet name")
private String name;
// Additional fields validated based on type
@Schema(description = "Dog breed (required for dogs)")
private String breed;
@Schema(description = "Indoor status (required for cats)")
private Boolean indoor;
@Schema(description = "Wingspan (required for birds)")
private Double wingspan;
}public @interface DependentRequired {
String name(); // Property name that triggers the requirement
String[] value(); // Array of properties that become required
Extension[] extensions() default {};
}Container annotation for multiple dependent required definitions.
@DependentRequiredMap({
@DependentRequired(name = "creditCard", value = {"cardNumber", "expiryDate", "cvv"}),
@DependentRequired(name = "paypal", value = {"paypalEmail"}),
@DependentRequired(name = "bankTransfer", value = {"accountNumber", "routingNumber"})
})
public class PaymentConfiguration {
// Payment configuration with multiple conditional requirements
}public @interface PatternProperty {
String pattern(); // Regular expression pattern
Schema schema() default @Schema(); // Schema for matching properties
Extension[] extensions() default {};
}
public @interface PatternProperties {
PatternProperty[] value(); // Array of pattern property definitions
}Install with Tessl CLI
npx tessl i tessl/maven-io-swagger-core-v3--swagger-annotations