-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Swagger 2.X Annotations
NOTE: Swagger Core 2.X produces OpenApi 3.0 definition files. If you're looking for swagger 1.5.X and OpenApi 2.0, please refer to 1.5.X JAX-RS Setup and [Annotations](Annotations 1.5.X).
Since version 2.1.7 Swagger Core supports also Jakarta namespace, with a parallel set of artifacts with -jakarta
suffix, providing the same functionality as the "standard" javax
namespace ones.
While behaviour described in this documentation is the same for both namespaces, artifact IDs, JEE / Jakarta EE versions and Jackson versions mentioned
refer to javax
namespace.
If you are using jakarta namespace:
- when you read artifact IDs in the form:
swagger-*
(e.g.swagger-core
), replace them withswagger-*-jakarta
(e.g.swagger-core-jakarta
) - when you read
javax.*
in package names, replace that withjakarta
(e.gjakarta.ws.rs.GET
) - when JEE / Jakarta EE dependencies are provided in examples, replace their version with Jakarta EE 9 versions.
- When Jackson dependencies are provided in examples, add the
jakarta
classifier for artifacts supporting it. See Jackson release notesJakarta
namespace Swagger Core artifacts need Jackson 2.12+
In order to generate the OpenAPI documentation, swagger-core offers a set of annotations to declare and manipulate the output. The core output is compliant with OpenAPI Specification. A user is not required to be familiar with the full aspects of the OpenAPI Specification in order to use it, but as a reference it may answer a few questions regarding the generated output.
This page introduces the annotations provided by swagger-core. They are grouped into:
The documentation for each annotation is meant as an overview of its usage. Each annotation also has links to its javadocs (both on the header and at the end of the overview).
For your convenience, the javadocs and petstore sample are available as well.
At the very least:
@javax.ws.rs.Path
is required at class level to have OpenAPI scan root resources, in compliance with JAX-RS spec.
@javax.ws.rs.<HTTP_METHOD>
(e.g. javax.ws.rs.GET
) is required at method level.
Note: swagger-jaxrs2 reader engine includes by default also methods of scanned resources which are not annotated with @Operation, as long as a jax-rs @Path is defined at class and/or method level, together with the http method annotation (@GET, @POST, etc).
This behaviour is controlled by configuration property readAllResources
which defaults to true. By setting this flag to
false only Operation
annotated methods are considered.
Name | Description |
---|---|
@OpenAPIDefinition | General metadata for an OpenAPI definition |
@Info | Info metadata for an OpenAPI definition |
@Contact | Properties to describe the contact person for an OpenAPI definition |
@License | Properties to describe the license for an OpenAPI definition |
Name | Description |
---|---|
@Operation | Describes an operation or typically a HTTP method against a specific path. |
@Parameter | Represents a single parameter in an OpenAPI Operation. |
@RequestBody | Represents the body of the request in an Operation |
@ApiResponse | Represents the response in an Operation |
@Tag | Represents tags for an operation or for the OpenAPI definition. |
@Server | Represents servers for an operation or for the OpenAPI definition. |
@Callback | Describes a set of requests |
@Link | Represents a possible design-time link for a response. |
Name | Description |
---|---|
@Schema | Allows the definition of input and output data. |
@ArraySchema | Allows the definition of input and output data for array types. |
@Content | Provides schema and examples for a particular media type. |
Name | Description |
---|---|
@SecurityRequirement | Lists the required security schemes to execute this operation. |
@SecurityScheme | Defines a security scheme that can be used by the operations. |
Name | Description |
---|---|
@Extension | Adds an extension with contained properties |
@ExtensionProperty | Adds custom properties to an extension |
Name | Description |
---|---|
@Hidden | Hides a resource, an operation or a property |
@ExternalDocumentation | Provides external documentation to a definition element |
The @OpenAPIDefinition
annotation may be used at class level to populate the definition-level fields of the OpenAPI document,
as in the example below.
It corresponds to the OpenAPI object
in the specification, and allows to define info, tags, externalDocs, security requirements and servers.
See also related annotations sections below.
@OpenAPIDefinition(
info = @Info(
title = "the title",
version = "0.0",
description = "My API",
license = @License(name = "Apache 2.0", url = "http://foo.bar"),
contact = @Contact(url = "http://gigantic-server.com", name = "Fred", email = "Fred@gigagantic-server.com")
),
tags = {
@Tag(name = "Tag 1", description = "desc 1", externalDocs = @ExternalDocumentation(description = "docs desc")),
@Tag(name = "Tag 2", description = "desc 2", externalDocs = @ExternalDocumentation(description = "docs desc 2")),
@Tag(name = "Tag 3")
},
externalDocs = @ExternalDocumentation(description = "definition docs desc"),
security = {
@SecurityRequirement(name = "req 1", scopes = {"a", "b"}),
@SecurityRequirement(name = "req 2", scopes = {"b", "c"})
},
servers = {
@Server(
description = "server 1",
url = "http://foo",
variables = {
@ServerVariable(name = "var1", description = "var 1", defaultValue = "1", allowableValues = {"1", "2"}),
@ServerVariable(name = "var2", description = "var 2", defaultValue = "1", allowableValues = {"1", "2"})
})
}
)
See the javadoc for a complete list of supported properties.
The @Info
annotation may be used in io.swagger.v3.oas.annotations.OpenAPIDefinition#info() to populate
the Info section of the OpenAPI document, as in the example below.
It corresponds to the Info object
in the specification.
@OpenAPIDefinition (info =
@Info(
title = "the title",
version = "0.0",
description = "My API",
license = @License(name = "Apache 2.0", url = "http://foo.bar"),
contact = @Contact(url = "http://gigantic-server.com", name = "Fred", email = "Fred@gigagantic-server.com")
)
)
See the javadoc for a complete list of supported properties.
The @Contact
annotation adds contact properties to the @Info
section of an OpenAPI definition - corresponding to the Contact object in the specification, as in the example below:
@OpenAPIDefinition (info =
@Info(
title = "the title",
version = "0.0",
description = "My API",
license = @License(name = "Apache 2.0", url = "http://foo.bar"),
contact = @Contact(url = "http://gigantic-server.com", name = "Fred", email = "Fred@gigagantic-server.com")
)
)
See the javadoc for a list of supported properties.
The @License
annotation adds license properties to the @Info
section of an OpenAPI definition - corresponding to the License object in the specification. As in the example above:
@OpenAPIDefinition (info =
@Info(
title = "the title",
version = "0.0",
description = "My API",
license = @License(name = "Apache 2.0", url = "http://foo.bar"),
contact = @Contact(url = "http://gigantic-server.com", name = "Fred", email = "Fred@gigagantic-server.com")
)
)
See the javadoc for a list of supported properties.
The annotation may be used to define a resource method as an OpenAPI Operation, and/or to define additional properties for the Operation.
Note: swagger-jaxrs2 reader engine includes by default also methods of scanned resources which are not annotated with @Operation, as long as a jax-rs @Path is defined at class and/or method level, together with the http method annotation (@GET, @POST, etc).
This behaviour is controlled by configuration property readAllResources
which defaults to true. By setting this flag to
false only Operation
annotated methods are considered.
The following fields can also alternatively be defined at method level (as repeatable annotations in case of arrays),
in this case method level annotations take precedence over Operation
annotation fields (see related section):
- tags:
@Tag
- externalDocs:
@ExternalDocumentation
- parameters:
@Parameter
- responses:
@ApiResponse
- requestBody:
@RequestBody
- security:
@SecurityRequirement
- servers:
@Server
- extensions:
@Extension
- hidden:
@Hidden
Example 1: A really simple usage would be:
@GET
@Operation(summary = "Get users",
description = "Get list of users")
public Response getUsers() {..}
Example 2: A sligthly extended example:
@GET
@Path("/{username}")
@Operation(summary = "Get user by user name",
responses = {
@ApiResponse(description = "The user",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = User.class))),
@ApiResponse(responseCode = "400", description = "User not found")})
public Response getUserByName(
@Parameter(description = "The name that needs to be fetched. Use user1 for testing. ", required = true) @PathParam("username") String username)
throws ApiException {
User user = userData.findUserByName(username);
if (null != user) {
return Response.ok().entity(user).build();
} else {
throw new NotFoundException(404, "User not found");
}
}
Example 3: Additional metadata defined:
@PUT
@Consumes("application/json")
@Operation(summary = "Update an existing pet",
tags = {"pets"},
security = @SecurityRequirement(
name = "petstore-auth",
scopes = "write:pets"),
responses = {
@ApiResponse(
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = Pet.class))),
@ApiResponse(responseCode = "400", description = "Invalid ID supplied"),
@ApiResponse(responseCode = "404", description = "Pet not found"),
@ApiResponse(responseCode = "405", description = "Validation exception") }
)
public Response updatePet(
@RequestBody(description = "Pet object that needs to be added to the store", required = true,
content = @Content(
schema = @Schema(implementation = Pet.class))) Pet pet) {
//..
}
The summary
of the annotation is a short description on the API. Since this is displayed in the list of operations in
Swagger-UI and the location is limited in size, this should be kept short (preferably shorter than 120 characters).
The description
allows you to give significantly more details about the operations.
responses
is a container for ApiResponse
annotations, allowing to define possible responses which can include the
return type of the method along with other meta data. Notice that the actual method declaration returns a Response
but
that is a general-purpose JAX-RS class and not the actual response sent to the user.
If the returned object is the actual result, it can be used directly instead of declaring it in the annotation.
Keep in mind that Java has type erasure, so using generics in the return type may not be parsed properly,
and the responses
should be used directly.
In the examples above, the @GET
or @PUT
JAX-RS annotation will be used as the (HTTP) method
field of the operation,
and the @Path
would tell us the path of the operation (operations are grouped under the same path, one for each HTTP method used).
Security related annotation is detailed in section @SecurityRequirement below.
The output for Example 2 would be:
/user/{username}:
get:
summary: Get user by user name
operationId: getUserByName
parameters:
- name: username
in: path
description: 'The name that needs to be fetched. Use user1 for testing. '
required: true
schema:
type: string
responses:
default:
description: The user
content:
application/json:
schema:
$ref: '#/components/schemas/User'
400:
description: User not found
For further details about this annotation, check out the javadocs and usage examples in tests
The annotation may be used on a method parameter to define it as a parameter for the operation, and/or to define additional properties for the Parameter. It can also be used independently in Operation.parameters() or at method level to add a parameter to the operation, even if not bound to any method parameter. swagger-jaxrs2 reader engine considers this annotation along with JAX-RS annotations, parameter type and context as input to resolve a method parameter into an OpenAPI Operation parameter.
The @Parameter
can be used in place of or together with the JAX-RS parameter annotations (@PathParam
, @QueryParam
, @HeaderParam
, @FormParam
and @BeanParam
).
While swagger-core / swagger-jaxrs2 scan these annotations by default, the @Parameter
allows to define more details for the parameter.
In the OpenAPI Specification, this translates to the Parameter Object.
An example of usage together with JAX-RS parameter annotation:
public Response login(
@Parameter(description = "The user name for login", required = true) @QueryParam("username") String username) { ... }
The output would be:
/pet/{petId}:
get:
summary: Find pet by ID
description: Returns a pet when 0 < ID <= 10. ID > 10 or nonintegers will simulate API error conditions
operationId: getPetById
parameters:
- name: username
in: query
description: The user name for login
required: true
schema:
type: string
And an example of usage on its own:
@Path("/subscription/{subscriptionId}")
public Response getSubscription(
@Parameter(in = "path", name = "subscriptionId",
required = true, description = "parameter description",
allowEmptyValue = true, allowReserved = true,
schema = @Schema(
type = "string",
format = "uuid",
description = "the generated UUID")) String subscriptionId) { ... }
The output would be:
/pet/{petId}:
get:
description: parameter description
operationId: getSubscription
parameters:
- name: subscriptionId
in: path
description: the generated UUID
required: true
schema:
type: string
format: uuid
description: the generated UUID
@Parameter
can be also used together with @FormDataParam
in multipart
scenarios to resolve the operation request body (see also the spec), for example:
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response upload(
@Parameter(in = ParameterIn.HEADER, name = "Authorization")
@HeaderParam(HttpHeaders.AUTHORIZATION) String creds,
@Parameter(schema = @Schema(implementation = Pet.class))
@FormDataParam("petData") String pet,
@Parameter(schema = @Schema(type = "string", format = "binary", description = "file 1"))
@FormDataParam("file1") InputStream file1,
@Parameter(schema = @Schema(type = "string", format = "binary", description = "file 2"))
@FormDataParam("file2") InputStream file2,
@Parameter(schema = @Schema(type = "string", format = "binary", description = "file 3"))
@FormDataParam("file3") InputStream file3) {
...
}
would resolve to:
/upload:
post:
operationId: upload
parameters:
- name: Authorization
in: header
schema:
type: string
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
petData:
$ref: '#/components/schemas/Pet'
file1:
type: string
description: file 1
format: binary
file2:
type: string
description: file 2
format: binary
file3:
type: string
description: file 3
format: binary
responses:
default:
description: default response
content:
application/json: {}
...
For further method parameters bound to the request body, see RequestBody below.
Multiple @Parameter
annotations can also be used in parameters
field of @Operation
annotation or as direct annotation(s) at method level;
this can be handy in various scenarios, for example:
- Wanting to hide a parameter as it is defined and override it with a completely different definition.
- Describe a parameter that is used by a filter or another resource prior to reaching the JAX-RS implementation.
When defining parameters in parameters
field of @Operation
annotation or at method level, it's important to set name
and in
for OpenAPIS's definitions to be proper.
In the sample below we can see an Operation definition with several parameters.
@GET
@Path("/")
@Operation(operationId = "operationId",
summary = "Operation Summary",
description = "Operation Description",
tags = {"Example Tag", "Second Tag"},
externalDocs =
@ExternalDocumentation(
description = "External documentation description",
url = "http://url.com"
),
parameters = {
@Parameter(in = "path", name = "subscriptionId",
required = true, description = "parameter description",
allowEmptyValue = true, allowReserved = true,
schema = @Schema(
type = "string",
format = "uuid",
description = "the generated UUID",
accessMode = Schema.AccessMode.READ_ONLY)
)},
responses = {
@ApiResponse(
responseCode = "200",
description = "voila!",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponsesResource.SampleResponseSchema.class)
)
),
@ApiResponse(
responseCode = "default",
description = "boo",
content = @Content(
mediaType = "*/*",
schema = @Schema(implementation = ResponsesResource.GenericError.class)
)
)
}
)
public Response getSummaryAndDescription() {
return Response.ok().entity("ok").build();
}
openapi: 3.0.1
tags:
- name: Example Tag
description: Example Tag
- name: Second Tag
description: Second Tag
paths:
/:
get:
tags:
- Example Tag
- Second Tag
summary: Operation Summary
description: Operation Description
externalDocs:
description: External documentation description
url: http://url.com
operationId: operationId
parameters:
- name: subscriptionId
in: path
description: parameter description
required: true
allowEmptyValue: true
allowReserved: true
schema:
type: string
description: the generated UUID
format: uuid
readOnly: true
responses:
200:
description: voila!
content:
application/json:
schema:
$ref: '#/components/schemas/SampleResponseSchema'
default:
description: boo
content:
'*/*':
schema:
$ref: '#/components/schemas/GenericError'
components:
schemas:
GenericError:
type: object
string:
type: string
description: the generated UUID
format: uuid
readOnly: true
SampleResponseSchema:
type: object
The same result is obtained applying the annotation at method level.
@GET
@Path("/")
@Operation(operationId = "operationId",
summary = "Operation Summary",
description = "Operation Description",
tags = {"Example Tag", "Second Tag"},
externalDocs =
@ExternalDocumentation(
description = "External documentation description",
url = "http://url.com"
),
responses = {
@ApiResponse(
responseCode = "200",
description = "voila!",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponsesResource.SampleResponseSchema.class)
)
),
@ApiResponse(
responseCode = "default",
description = "boo",
content = @Content(
mediaType = "*/*",
schema = @Schema(implementation = ResponsesResource.GenericError.class)
)
)
}
)
@Parameter(in = "path", name = "subscriptionId",
required = true, description = "parameter description",
allowEmptyValue = true, allowReserved = true,
schema = @Schema(
type = "string",
format = "uuid",
description = "the generated UUID",
accessMode = Schema.AccessMode.READ_ONLY)
)
public Response getSummaryAndDescription() {
return Response.ok().entity("ok").build();
}
For further details about this annotation, check out the javadocs and usage examples in tests
The annotation may be used on a method parameter to define it as the Request Body of the operation, and/or to define additional properties for such request body. It maps to OpenAPI spec RequestBody
It can also be used at method level or as field of Operation#requestBody, in which case it will not be bound to the specific parameter.
Also without a @RequestBody
annotated parameter and with no @RequestBody
annotation at method level or as field of Operation#requestBody, if a parameter is annotated with @Parameter
with no in
field specified and no JAX-RS annotation (@QueryParam
, @HeaderParam
, @BeanParam
), the parameter is resolved as a request body.This happens only when the http method is associated with the @PUT
or @POST
verb. In case of multiple such parameters, only the first is considered.
public Response addPet(
@Parameter(description = "Pet object that needs to be added to the store", required = true) Pet pet) { ... }
The output would be:
requestBody:
description: Pet object that needs to be added to the store
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
required: true
We can add more meta data with the @RequestBody
annotation:
@POST
@Path("/user")
@Operation(summary = "Create user",
description = "This can only be done by the logged in user.")
public Response methodWithRequestBodyAndTwoParameters(
@RequestBody(description = "Created user object", required = true,
content = @Content(
schema = @Schema(implementation = User.class))) User user,
@QueryParam("name") String name, @QueryParam("code") String code)
{ ... }
The output would be:
post:
summary: Create user
description: This can only be done by the logged in user.
operationId: methodWithRequestBodyAndTwoParameters
parameters:
- name: name
in: query
schema:
type: string
- name: code
in: query
schema:
type: string
requestBody:
description: Created user object
content:
'*/*':
schema:
$ref: '#/components/schemas/User'
required: true
responses:
default:
description: no description
The @RequestBody
might be affected by the @Consumes
annotation: for every media type defined there will be an associated mediaType in the RequestBody content.
@POST
@Path("/pet")
@Operation(summary = "Create pet",
description = "Creating pet.")
@Consumes({"application/json", "application/xml"})
public Response methodWithTwoRequestBodyWithoutAnnotationAndTwoConsumes(
Pet pet, User user) { .. }
The output would be:
post:
summary: Create pet
description: Creating pet.
operationId: methodWithTwoRequestBodyWithoutAnnotationAndTwoConsumes
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
responses:
default:
description: no description
For further details about this annotation, usage and edge cases, check out the javadocs) and usage examples in specific test class and other tests.
The annotation may be used at method level or as field of @Operation to define one or more responses of the Operation. It maps to OpenAPI spec ApiResponse
swagger-jaxrs2 reader engine considers this annotation along with method return type and context as input to resolve the OpenAPI Operation responses, along with the response body content/schema if applicable.
If no @ApiResponse
is provided at method level or in the @Operation
annotation, a default response will be generated,
inferring when possible the content/schema from the method return type.
A simple example of usage:
@DELETE
@Path("/{username}")
@Operation(summary = "Delete user",
description = "This can only be done by the logged in user.")
@ApiResponse(responseCode = "200", description = "user deteled")
@ApiResponse(responseCode = "400", description = "Invalid username supplied")
@ApiResponse(responseCode = "404", description = "User not found")
public Response deleteUser(
@Parameter(description = "The name that needs to be deleted", required = true) @PathParam("username") String username) {...}
or
@DELETE
@Path("/{username}")
@Operation(summary = "Delete user",
description = "This can only be done by the logged in user.",
responses = {
@ApiResponse(responseCode = "200", description = "user deteled"),
@ApiResponse(responseCode = "400", description = "Invalid username supplied"),
@ApiResponse(responseCode = "404", description = "User not found")})
public Response deleteUser(
@Parameter(description = "The name that needs to be deleted", required = true) @PathParam("username") String username) {...}
In this case the response would be:
delete:
summary: Delete user
description: This can only be done by the logged in user.
operationId: deleteUser
parameters:
- name: username
in: path
description: The name that needs to be deleted
required: true
schema:
type: string
responses:
200:
description: user deteled
400:
description: Invalid username supplied
404:
description: User not found
A more complex example, providing schema and examples:
@Operation(
summary = "Simple get operation",
description = "Defines a simple get operation with no inputs and a complex",
operationId = "getWithPayloadResponse",
deprecated = true
)
@ApiResponse(
responseCode = "200",
description = "voila!",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = SampleResponseSchema.class)
))
@ApiResponse(
description = "boo",
content = @Content(
mediaType = "*/*",
schema = @Schema(implementation = GenericError.class),
examples = {
@ExampleObject(name = "boo", value = "example",
summary = "example of boo", externalValue = "example of external value")
}
)
)
@Path("/path")
@GET
public void simpleGet() {
}
get:
summary: Simple get operation
description: Defines a simple get operation with no inputs and a complex
operationId: getWithPayloadResponse
responses:
200:
description: voila!
content:
application/json:
schema:
$ref: '#/components/schemas/SampleResponseSchema'
default:
description: boo
content:
'*/*':
schema:
$ref: '#/components/schemas/GenericError'
examples:
boo:
summary: example of boo
description: boo
value: example
externalValue: example of external value
deprecated: true
An example with no @ApiRepsonse
defined:
@GET
@Operation(description = "returns a value")
@Path("/findAll")
public SimpleResponse getSimpleResponseWithParameters(...){ ... }
In this case the response would be resolved from the return type:
responses:
default:
description: no description
content:
'*/*':
schema:
$ref: '#/components/schemas/SimpleResponse'
The @Produces
annotation can affect the contents of this annotation; @Produces
response media types are added to the content
of operation responses:
@Produces({"application/json", "application/xml"})
public class UserResource {
@GET
@Path("/login")
@Operation(summary = "Logs user into the system",
responses = {
@ApiResponse(description = "Successfully logged in",
content = @Content(schema = @Schema(implementation = String.class))),
@ApiResponse(responseCode = "400", description = "Invalid username/password supplied")})
public Response loginUser( ... ){ ... }
}
In this case the result would be:
/user/login:
get:
summary: Logs user into the system
operationId: loginUser
parameters:
- name: username
in: query
description: The user name for login
required: true
schema:
type: string
- name: password
in: query
description: The password for login in clear text
required: true
schema:
type: string
responses:
default:
description: Successfully logged in
content:
application/json:
schema:
type: string
application/xml:
schema:
type: string
400:
description: Invalid username/password supplied
For further details about this annotation, usage and edge cases, check out the javadocs @ApiResponse) and usage examples in specific test class and other tests.
The annotation may be applied at class or method level, or in @Operation#tags() to define tags for the single operation (when applied at method level) or for all operations of a class (when applied at class level).
When applied at method or class level, if only a name is provided, the tag will be added to operation only; if additional
fields are also defined, like description or externalDocs, the Tag will also be added to openAPI.tags
field.
It maps to OpenAPI spec Tag
A full example:
@OpenAPIDefinition(tags = {
@Tag(name = "Definition First Tag"),
@Tag(name = "Definition Second Tag full", description = "desc definition")
})
@Tag(name = "Second Tag")
@Tag(name = "Fourth Tag Full", description = "desc class", externalDocs = @ExternalDocumentation(description = "docs desc class"))
@Tag(name = "Fifth Tag Full", description = "desc class", externalDocs = @ExternalDocumentation(description = "docs desc class"))
@Tag(name = "Sixth Tag")
public class TagsResource {
@GET
@Path("/")
@Operation(tags = {"Example Tag", "Second Tag"})
@Tag(name = "Third Tag")
@Tag(name = "Second Tag")
@Tag(name = "Fourth Tag Full", description = "desc", externalDocs = @ExternalDocumentation(description = "docs desc"))
public Response getTags() {
return Response.ok().entity("ok").build();
}
}
Resolves into:
openapi: 3.0.1
tags:
- name: Definition First Tag
- name: Definition Second Tag full
description: desc definition
- name: Fourth Tag Full
description: desc
externalDocs:
description: docs desc
- name: Fifth Tag Full
description: desc class
externalDocs:
description: docs desc class
paths:
/:
get:
tags:
- Third Tag
- Second Tag
- Fourth Tag Full
- Example Tag
- Fifth Tag Full
- Sixth Tag
operationId: getTags
responses:
default:
description: default response
It can also be used in @OpenAPIDefinition#tags() to define spec level tags:
@OpenAPIDefinition(
tags = {
@Tag(name = "Tag 1", description = "desc 1", externalDocs = @ExternalDocumentation(description = "docs desc")),
@Tag(name = "Tag 2", description = "desc 2", externalDocs = @ExternalDocumentation(description = "docs desc 2")),
@Tag(name = "Tag 3")
}
)
static class ClassWithAnnotation {..}
openapi: 3.0.1
tags:
- name: Tag 1
description: desc 1
externalDocs:
description: docs desc
- name: Tag 2
description: desc 2
externalDocs:
description: docs desc 2
- name: Tag 3
For further details about this annotation, usage and edge cases, check out the javadocs @Tag) and usage examples in specific test class and other tests.
The annotation may be applied at class or method level, or in @Operation#servers() to define servers for the single operation (when applied at method level) or for all operations of a class (when applied at class level).
It maps to OpenAPI spec Server
A full example:
@OpenAPIDefinition(
servers = {
@Server(
description = "definition server 1",
url = "http://definition1",
variables = {
@ServerVariable(name = "var1", description = "var 1", defaultValue = "1", allowableValues = {"1", "2"}),
@ServerVariable(name = "var2", description = "var 2", defaultValue = "1", allowableValues = {"1", "2"})
})
}
)
@Server(
description = "class server 1",
url = "http://class1",
variables = {
@ServerVariable(name = "var1", description = "var 1", defaultValue = "1", allowableValues = {"1", "2"}),
@ServerVariable(name = "var2", description = "var 2", defaultValue = "1", allowableValues = {"1", "2"})
})
@Server(
description = "class server 2",
url = "http://class2",
variables = {
@ServerVariable(name = "var1", description = "var 1", defaultValue = "1", allowableValues = {"1", "2"})
})
public class ServersResource {
@GET
@Path("/")
@Operation(servers = {
@Server(
description = "operation server 1",
url = "http://op1",
variables = {
@ServerVariable(name = "var1", description = "var 1", defaultValue = "1", allowableValues = {"1", "2"})
})
})
@Server(
description = "method server 1",
url = "http://method1",
variables = {
@ServerVariable(name = "var1", description = "var 1", defaultValue = "1", allowableValues = {"1", "2"})
})
@Server(
description = "method server 2",
url = "http://method2"
)
public Response getServers() {
return Response.ok().entity("ok").build();
}
}
Resolves into:
openapi: 3.0.1
servers:
- url: http://definition1
description: definition server 1
variables:
var1:
description: var 1
enum:
- "1"
- "2"
default: "1"
var2:
description: var 2
enum:
- "1"
- "2"
default: "1"
paths:
/:
get:
operationId: getServers
responses:
default:
description: default response
servers:
- url: http://class1
description: class server 1
variables:
var1:
description: var 1
enum:
- "1"
- "2"
default: "1"
var2:
description: var 2
enum:
- "1"
- "2"
default: "1"
- url: http://class2
description: class server 2
variables:
var1:
description: var 1
enum:
- "1"
- "2"
default: "1"
- url: http://method1
description: method server 1
variables:
var1:
description: var 1
enum:
- "1"
- "2"
default: "1"
- url: http://method2
description: method server 2
variables: {}
- url: http://op1
description: operation server 1
variables:
var1:
description: var 1
enum:
- "1"
- "2"
default: "1"
It can also be used in @OpenAPIDefinition#servers() to define spec level servers:
@OpenAPIDefinition(
servers = {
@Server(
description = "server 1",
url = "http://foo",
variables = {
@ServerVariable(name = "var1", description = "var 1", defaultValue = "1", allowableValues = {"1", "2"}),
@ServerVariable(name = "var2", description = "var 2", defaultValue = "1", allowableValues = {"1", "2"})
})
}
)
static class ClassWithAnnotation {..}
openapi: 3.0.1
servers:
- url: http://foo
description: server 1
variables:
var1:
description: var 1
enum:
- "1"
- "2"
default: "1"
var2:
description: var 2
enum:
- "1"
- "2"
default: "1"
For further details about this annotation, usage and edge cases, check out the javadocs @Server) and usage examples in specific test class and other tests.
Note: class level servers annotation are supported in latest 2.0.0-SNAPSHOT
and next release
The annotation may be used at method level to add one ore more callbacks to the operation definition.
It maps to OpenAPI spec Callback
A usage example:
@Path("/test")
@POST
@Callback(
callbackUrlExpression = "http://$request.query.url",
name = "subscription",
operation = {
@Operation(
method = "post",
description = "payload data will be sent",
parameters = {
@Parameter(in = ParameterIn.PATH, name = "subscriptionId", required = true, schema = @Schema(
type = "string",
format = "uuid",
description = "the generated UUID",
accessMode = Schema.AccessMode.READ_ONLY
))
},
responses = {
@ApiResponse(
responseCode = "200",
description = "Return this code if the callback was received and processed successfully"
),
@ApiResponse(
responseCode = "205",
description = "Return this code to unsubscribe from future data updates"
),
@ApiResponse(
responseCode = "default",
description = "All other response codes will disable this callback subscription"
)
}),
@Operation(
method = "get",
description = "payload data will be received"
),
@Operation(
method = "put",
description = "payload data will be sent"
)})
@Operation(description = "subscribes a client to updates relevant to the requestor's account, as " +
"identified by the input token. The supplied url will be used as the delivery address for response payloads")
public SubscriptionResponse subscribe(@Schema(required = true, description = "the authentication token " +
"provided after initially authenticating to the application") @HeaderParam("x-auth-token") String token,
@Schema(required = true, description = "the URL to call with response " +
"data") @QueryParam("url") String url) {
return null;
}
static class SubscriptionResponse {
private String subscriptionUuid;
}
The output would be:
callbacks:
subscription:
http://$request.query.url:
post:
description: payload data will be sent
parameters:
- name: subscriptionId
in: path
required: true
schema:
type: string
description: the generated UUID
format: uuid
readOnly: true
responses:
200:
description: Return this code if the callback was received and processed successfully
205:
description: Return this code to unsubscribe from future data updates
default:
description: All other response codes will disable
For further details about this annotation, usage and edge cases, check out the javadocs @Callback) and usage examples in specific test resource class and test class.
The annotation may be applied in @ApiResponse#links() to add OpenAPI links to a response.
Please see OpenAPI spec Link for futher details.
A usage example:
static class ClassWithOperationAndLinks {
@Path("/users")
@Operation(operationId = "getUser",
responses = {
@ApiResponse(description = "test description",
content = @Content(mediaType = "*/*", schema = @Schema(ref = "#/components/schemas/User")),
links = {
@Link(
name = "address",
operationId = "getAddress",
parameters = @LinkParameter(
name = "userId",
expression = "$request.query.userId"))
})}
)
@GET
public User getUser(@QueryParam("userId") String userId) {
return null;
}
@Path("/addresses")
@Operation(operationId = "getAddress",
responses = {
@ApiResponse(content = @Content(mediaType = "*/*",
schema = @Schema(ref = "#/components/schemas/Address")),
description = "test description")
})
@GET
public Address getAddress(@QueryParam("userId") String userId) {
return null;
}
}
The output would be:
paths:
/users:
get:
operationId: getUser
parameters:
- name: userId
in: query
schema:
type: string
responses:
default:
description: test description
content:
'*/*':
schema:
$ref: '#/components/schemas/User'
links:
address:
operationId: getAddress
parameters:
userId: $request.query.userId
/addresses:
get:
operationId: getAddress
parameters:
- name: userId
in: query
schema:
type: string
responses:
default:
description: test description
content:
'*/*':
schema:
$ref: '#/components/schemas/Address'
For further details about this annotation, usage and edge cases, check out the javadocs @Link and test class.
The annotation may be used to define a Schema for a set of elements of the OpenAPI spec, and/or to define additional properties for the schema. It is applicable e.g. to parameters, schema classes (aka "models"), properties of such models, request and response content, header.
swagger-core resolver and swagger-jaxrs2 reader engine consider this annotation along with JAX-RS annotations, element type and context as input to resolve the annotated element into an OpenAPI schema definition for such element.
The annotation may be used also to override partly (e.g. the name) or fully (e.g providing a completely different representation)
the schema of an element; for example if a specific class is provided as value of Schema#implementation()
it will override
the element type.
The annotation @ArraySchema shall be used for array elements; ArraySchema
and Schema
cannot coexist.
See also OpenAPI spec Schema in the OpenAPI Specification.
@Schema
can be used to annotate directly a model bean:
@Schema(name="DifferentModel", description="Sample model for the documentation")
class OriginalModel {...}
"DifferentModel": {
"description": "Sample model for the documentation",
.
.
}
And/Or a schema property:
@Schema(description = "pet status in the store", allowableValues = {"available","pending","sold"})
public String getStatus() {
return status;
}
And/Or in the schema
field of @Parameter
, @Header
or @Content
annotations
@ApiResponse(description = "Pets matching criteria",
content = @Content(schema = @Schema(implementation = Pet.class))
),
For further details about this annotation, usage and edge cases, check out:
- the javadocs
- usage examples in test "models"
- core tests
- jaxrs tests
The annotation may be used to define a schema of type "array" for a set of elements of the OpenAPI spec, and/or to define additional properties for the schema. It is applicable e.g. to parameters, schema classes (aka "models"), properties of such models, request and response content, header.
swagger-core resolver and swagger-jaxrs2 reader engine consider this annotation along with JAX-RS annotations, element type and context as input to resolve the annotated element into an OpenAPI schema definition for such element.
The annotation may be used also to override partly (e.g. the name) or fully (e.g providing a completely different representation)
the schema of an element; for example if a specific class is provided as value of Schema#implementation()
it will override
the element type.
The annotation @Schema shall be used for non array elements; ArraySchema
and Schema
cannot coexist.
See also OpenAPI spec Schema in the OpenAPI Specification.
An example applied to a response:
@Operation(
summary = "Get a list of users",
description = "Get a list of users registered in the system",
responses = {@ApiResponse(
responseCode = "200",
description = "The response for the user request",
content = {
@Content(
mediaType = "application/json",
array = @ArraySchema(schema = @Schema(implementation = User.class))
)
})
}
)
@GET
@SecurityRequirement(name = "JWT")
@Path("/user")
public List<User> getUsers() {
return null;
}
class User {
public String foo;
}
with output:
openapi: 3.0.1
paths:
/user:
get:
summary: Get a list of users
description: Get a list of users registered in the system
operationId: getUsers
responses:
200:
description: The response for the user request
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
security:
- JWT: []
components:
schemas:
User:
type: object
properties:
foo:
type: string
For further details about this annotation, usage and edge cases, check out:
- the javadocs
- usage examples in test "models"
- core tests
- jaxrs tests
The annotation may be used to define the content/media type of a parameter, request or response, by definining it as field
of @Parameter
, RequestBody
and ApiResponse
annotations, and matches related OpenAPI specification content
property
of Parameter Object
, Request Body Object
and Response Object
.
If @Content#schema
is defined, swagger-jaxrs2 reader engine will consider it along with JAX-RS annotations, element type
and context as input to resolve the annotated element into an OpenAPI schema definition for such element.
See also OpenAPI spec Media Type in the OpenAPI Specification.
@ApiResponse(
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = Pet.class)))
responses:
default:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
400:
description: Invalid status value
For further details about this annotation, usage and edge cases, check out:
The annotation may be used at class level (also on multiple classes) to add securitySchemes to spec components section.
See also OpenAPI spec Security Scheme in the OpenAPI Specification.
An example:
@SecurityScheme(name = "myOauth2Security",
type = "oauth2",
flows = @OAuthFlows(
implicit = @OAuthFlow(authorizationUrl = "http://url.com/auth",
scopes = @Scopes(name = "write:pets", description = "modify pets in your account"))))
static class OAuth2SchemeOnClass { ... }
The output would be:
components:
securitySchemes:
myOauth2Security:
type: oauth2
flows:
implicit:
authorizationUrl: http://url.com/auth
scopes:
name: write:pets
description: modify pets in your account
For further details about this annotation, usage and edge cases, check out:
The annotation may be applied at class or method level, or in @Operation#security() to define security requirements for the single operation (when applied at method level) or for all operations of a class (when applied at class level).
It can also be used in @OpenAPIDefinition#security() to define spec level security.
See also OpenAPI spec Security Requirement in the OpenAPI Specification.
An example:
@SecurityScheme(name = "myOauth2Security",
type = "oauth2",
flows = @OAuthFlows(
implicit = @OAuthFlow(authorizationUrl = "http://url.com/auth",
scopes = @Scopes(name = "write:pets", description = "modify pets in your account"))))
static class SecurityRequirementOnClass {
@Operation(description = "operation")
@SecurityRequirement(name = "myOauth2Security", scopes = "write: read")
@GET
@Path("/")
public Response getResponse(){
return null;
}
}
The output would be:
openapi: 3.0.1
paths:
/:
get:
description: operation
operationId: getResponse
responses:
default:
description: no description
content:
'*/*':
schema:
$ref: '#/components/schemas/Response'
security:
- myOauth2Security:
- 'write: read'
components:
schemas:
Response:
type: object
properties:
context:
type: object
additionalProperties: {}
cancelled:
type: boolean
done:
type: boolean
securitySchemes:
myOauth2Security:
type: oauth2
flows:
implicit:
authorizationUrl: http://url.com/auth
scopes:
name: write:pets
description: modify pets in your account
For further details about this annotation, usage and edge cases, check out:
The extension annotation allows adding vendor extensions to an OpenAPI definition.
See test resource classes for usage examples
An individual property within an extension - see previous @Extension section for examples.
Note that @ExtensionProperty
boolean field parseValue
, when set to true
, allows to have the extension value parsed and serialized as JSON/YAML:
@Operation(extensions = {
@Extension(properties = {
@ExtensionProperty(name = "codes", value = "[\"11\", \"12\"]", parseValue = true),
@ExtensionProperty(name = "name", value = "Josh")})
})
public Response getSummaryAndDescription() {...}
will be resolved into:
x-name: "Josh"
x-codes:
- "11"
- "12"
Marks a given resource, class or bean type as hidden, skipping while reading / resolving.
An example:
@Path("/user")
@Produces({"application/json", "application/xml"})
public class HiddenAnnotatedUserResourceMethodAndData {
UserData userData = new UserData();
@POST
@Hidden
@Operation(summary = "Create user",
description = "This can only be done by the logged in user.")
@Path("/1")
public Response createUser(
@Parameter(description = "Created user object", required = true) User user) {
userData.addUser(user);
return Response.ok().entity("").build();
}
@POST
@Operation(summary = "Create user",
description = "This can only be done by the logged in user.")
@Path("/2")
public Response createUserWithHiddenBeanProperty(
@Parameter(description = "Created user object", required = true) UserResourceBean user) {
return Response.ok().entity("").build();
}
}
The output would be:
openapi: 3.0.1
paths:
/user/2:
post:
summary: Create user
description: This can only be done by the logged in user.
operationId: createUserWithHiddenBeanProperty
requestBody:
description: Created user object
content:
'*/*':
schema:
$ref: '#/components/schemas/UserResourceBean'
required: true
responses:
default:
description: default response
components:
schemas:
UserResourceBean:
type: object
properties:
foo:
type: string
For further details about this annotation, usage and edge cases, check out:
- the javadocs
- test class
The annotation may be used at method level or as field of Operation#externalDocs to add a reference to an external resource for
extended documentation of an Operation
.
It may also be used to add external documentation to Tag
, Header
or Schema
, or as field of OpenAPIDefinition#externalDocs.
An example:
@Path("/user")
@Produces({"application/json", "application/xml"})
public class HiddenAnnotatedUserResourceMethodAndData {
UserData userData = new UserData();
@POST
@Hidden
@Operation(summary = "Create user",
description = "This can only be done by the logged in user.")
@Path("/1")
public Response createUser(
@Parameter(description = "Created user object", required = true) User user) {
userData.addUser(user);
return Response.ok().entity("").build();
}
@POST
@Operation(summary = "Create user",
description = "This can only be done by the logged in user.")
@Path("/2")
public Response createUserWithHiddenBeanProperty(
@Parameter(description = "Created user object", required = true) UserResourceBean user) {
return Response.ok().entity("").build();
}
}
The output would be:
openapi: 3.0.1
paths:
/user/2:
post:
summary: Create user
description: This can only be done by the logged in user.
operationId: createUserWithHiddenBeanProperty
requestBody:
description: Created user object
content:
'*/*':
schema:
$ref: '#/components/schemas/UserResourceBean'
required: true
responses:
default:
description: default response
components:
schemas:
UserResourceBean:
type: object
properties:
foo:
type: string
For further details about this annotation, usage and edge cases, check out: