Java annotations for defining Swagger API documentation and OpenAPI specification metadata
—
Annotations for documenting data models, their properties, and relationships. These annotations provide detailed metadata about the structure, constraints, and documentation for data transfer objects and entity classes used in API requests and responses.
Provides additional information about Swagger models. Classes are automatically introspected when used as types in operations, but this annotation allows manipulation of the model structure.
/**
* Provides additional information about Swagger models
* Classes are introspected automatically, this allows structure manipulation
* Target: TYPE (classes)
* Retention: RUNTIME
* Inherited: true
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@interface ApiModel {
/**
* Provide an alternative name for the model
* By default, the class name is used
*/
String value() default "";
/** Provide a longer description of the class */
String description() default "";
/** Provide a superclass for the model to allow describing inheritance */
Class<?> parent() default Void.class;
/**
* Supports model inheritance and polymorphism
* Name of the field used as a discriminator for asserting sub type
*/
String discriminator() default "";
/** Array of sub types inheriting from this model */
Class<?>[] subTypes() default {};
/**
* Specifies a reference to the corresponding type definition
* Overrides any other metadata specified
*/
String reference() default "";
}Usage Examples:
// Basic model documentation
@ApiModel(description = "User account information")
public class User {
// properties
}
// Model with alternative name
@ApiModel(
value = "UserAccount",
description = "Complete user account with profile and settings"
)
public class User {
// properties
}
// Inheritance and polymorphism
@ApiModel(
description = "Base shape class",
discriminator = "shapeType",
subTypes = {Circle.class, Rectangle.class, Triangle.class}
)
public abstract class Shape {
@ApiModelProperty(value = "Type of shape", required = true)
private String shapeType;
// common properties
}
@ApiModel(description = "Circle shape")
public class Circle extends Shape {
@ApiModelProperty(value = "Circle radius", required = true)
private double radius;
}
@ApiModel(description = "Rectangle shape")
public class Rectangle extends Shape {
@ApiModelProperty(value = "Rectangle width", required = true)
private double width;
@ApiModelProperty(value = "Rectangle height", required = true)
private double height;
}Adds and manipulates data of a model property. Can be used on fields or getter methods.
/**
* Adds and manipulates data of a model property
* Target: METHOD (getters), FIELD
* Retention: RUNTIME
*/
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface ApiModelProperty {
/** Brief description of the property */
String value() default "";
/**
* Override the name of the property
* By default, field name or getter method name is used
*/
String name() default "";
/**
* Limits allowable values for this property
* Same format as @ApiParam allowableValues:
* - List: "first, second, third"
* - Range: "range[1, 5]", "range(1, 5)", "range[1, 5)"
* - Min/Max: "range[1, infinity]", "range[-infinity, 100]"
*/
String allowableValues() default "";
/**
* Property access level for filtering
* See io.swagger.core.filter.SwaggerSpecFilter for details
*/
String access() default "";
/** Additional notes about the property */
String notes() default "";
/**
* Data type of the property
* Override automatically detected type
*/
String dataType() default "";
/** Specifies if the property is required */
boolean required() default false;
/**
* Position of property in model
* Used for ordering properties in documentation
*/
int position() default 0;
/** Hides the property from model documentation */
boolean hidden() default false;
/** Example value for the property */
String example() default "";
/**
* Specifies that property is read-only
* Property will be sent in response but not expected in request
* @deprecated As of 1.5.19, replaced by accessMode()
*/
@Deprecated
boolean readOnly() default false;
/**
* Allows specifying the access mode of a model property
* @since 1.5.19
*/
AccessMode accessMode() default AccessMode.AUTO;
/**
* Specifies a reference to corresponding property definition
* Overrides other metadata if specified
*/
String reference() default "";
/** Specifies that property allows empty values */
boolean allowEmptyValue() default false;
/** Optional array of extensions */
Extension[] extensions() default @Extension(properties = @ExtensionProperty(name = "", value = ""));
}Usage Examples:
@ApiModel(description = "User account")
public class User {
@ApiModelProperty(
value = "Unique user identifier",
example = "12345",
readOnly = true,
position = 1
)
private Long id;
@ApiModelProperty(
value = "User's full name",
required = true,
example = "John Doe",
position = 2
)
private String name;
@ApiModelProperty(
value = "Email address",
required = true,
example = "john.doe@example.com",
notes = "Must be a valid email format",
position = 3
)
private String email;
@ApiModelProperty(
value = "User age",
allowableValues = "range[13, 120]",
example = "25",
position = 4
)
private Integer age;
@ApiModelProperty(
value = "Account status",
allowableValues = "ACTIVE, INACTIVE, SUSPENDED, PENDING",
example = "ACTIVE",
position = 5
)
private UserStatus status;
@ApiModelProperty(
value = "Account creation timestamp",
example = "2023-01-15T10:30:00Z",
readOnly = true,
dataType = "string",
notes = "ISO 8601 timestamp format"
)
private LocalDateTime createdAt;
@ApiModelProperty(hidden = true)
private String internalId;
// Getters and setters
}
// Using on getter methods
@ApiModel(description = "Product information")
public class Product {
private String name;
private BigDecimal price;
private String currency;
@ApiModelProperty(
value = "Product name",
required = true,
example = "Wireless Headphones"
)
public String getName() {
return name;
}
@ApiModelProperty(
value = "Formatted price string",
example = "$99.99 USD",
readOnly = true
)
public String getFormattedPrice() {
return String.format("$%.2f %s", price, currency);
}
}@ApiModel(description = "User profile with address")
public class UserProfile {
@ApiModelProperty(value = "Basic user information", required = true)
private User user;
@ApiModelProperty(value = "Home address")
private Address homeAddress;
@ApiModelProperty(value = "Work address")
private Address workAddress;
}
@ApiModel(description = "Address information")
public class Address {
@ApiModelProperty(value = "Street address", required = true, example = "123 Main St")
private String street;
@ApiModelProperty(value = "City", required = true, example = "Springfield")
private String city;
@ApiModelProperty(value = "State or province", example = "IL")
private String state;
@ApiModelProperty(value = "Postal code", example = "62701")
private String postalCode;
@ApiModelProperty(
value = "Country code",
example = "US",
allowableValues = "US, CA, MX, UK, DE, FR"
)
private String country;
}@ApiModel(description = "Shopping cart")
public class ShoppingCart {
@ApiModelProperty(value = "Cart items")
private List<CartItem> items;
@ApiModelProperty(value = "Applied discount codes")
private Set<String> discountCodes;
@ApiModelProperty(
value = "Item quantities by product ID",
dataType = "java.util.Map"
)
private Map<Long, Integer> quantities;
}
@ApiModel(description = "Cart item")
public class CartItem {
@ApiModelProperty(value = "Product information", required = true)
private Product product;
@ApiModelProperty(
value = "Quantity",
required = true,
allowableValues = "range[1, 99]",
example = "2"
)
private Integer quantity;
@ApiModelProperty(value = "Line total", readOnly = true)
private BigDecimal lineTotal;
}@ApiModel(description = "Generic API response wrapper")
public class ApiResponse<T> {
@ApiModelProperty(value = "Success status", example = "true")
private boolean success;
@ApiModelProperty(value = "Response message", example = "Operation completed successfully")
private String message;
@ApiModelProperty(value = "Response data")
private T data;
@ApiModelProperty(value = "Error details")
private List<String> errors;
@ApiModelProperty(value = "Response timestamp", readOnly = true)
private LocalDateTime timestamp;
}
// Usage in operations
@ApiOperation(
value = "Get user",
response = ApiResponse.class,
notes = "Returns user data wrapped in generic response"
)
@GET
@Path("/{id}")
public ApiResponse<User> getUser(@PathParam("id") Long id) {
// implementation
}@ApiModel(description = "User registration request")
public class UserRegistrationRequest {
@ApiModelProperty(
value = "Username",
required = true,
allowableValues = "range[3, 50]",
example = "johndoe",
notes = "Must be unique, alphanumeric characters and underscores only"
)
private String username;
@ApiModelProperty(
value = "Password",
required = true,
allowableValues = "range[8, 128]",
notes = "Must contain at least one letter, one number, and one special character"
)
private String password;
@ApiModelProperty(
value = "Email address",
required = true,
example = "john@example.com",
notes = "Must be valid email format"
)
private String email;
@ApiModelProperty(
value = "Date of birth",
example = "1990-01-15",
dataType = "string",
notes = "ISO date format (YYYY-MM-DD), user must be at least 13 years old"
)
private LocalDate dateOfBirth;
@ApiModelProperty(
value = "Terms acceptance",
required = true,
allowableValues = "true",
notes = "Must be true to register"
)
private Boolean acceptTerms;
}/**
* Access mode for model properties
* @since 1.5.19
*/
enum AccessMode {
/** Automatically determine access mode based on context */
AUTO,
/** Property is read-only (response only) */
READ_ONLY,
/** Property is read-write (request and response) */
READ_WRITE
}@ApiModel(description = "User account status")
public enum UserStatus {
@ApiModelProperty("Active user account")
ACTIVE,
@ApiModelProperty("Temporarily inactive account")
INACTIVE,
@ApiModelProperty("Suspended due to policy violation")
SUSPENDED,
@ApiModelProperty("Pending email verification")
PENDING_VERIFICATION,
@ApiModelProperty("Account marked for deletion")
PENDING_DELETION;
}
@ApiModel(description = "Application constants")
public class AppConstants {
@ApiModelProperty(value = "Maximum file upload size in bytes", example = "10485760")
public static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
@ApiModelProperty(value = "Supported file types")
public static final String[] SUPPORTED_FILE_TYPES = {"jpg", "png", "pdf", "doc", "docx"};
@ApiModelProperty(value = "Default page size for pagination", example = "20")
public static final int DEFAULT_PAGE_SIZE = 20;
}required = true for mandatory fieldsposition attributeallowableValues for validation rulesdiscriminator and subTypes for polymorphic modelsreadOnly = true for computed or auto-generated propertieshidden = true for properties not exposed in APInotesInstall with Tessl CLI
npx tessl i tessl/maven-io-swagger--swagger-annotations