-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Swagger 2.X Getting started
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
NOTE: Since version 2.2.0 Swagger Core supports OpenAPI 3.1; see this page for details
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+
NOTE: swagger-core
is based on OpenAPI specification; check out related docs for an overview of Swagger ecosystem.
swagger-core
is an open source Java implementation of Swagger/OpenAPI, providing:
-
swagger-models
: OpenAPI specification Java implementation -
swagger-core
: resolves (annotated) java POJOs into OpenAPI schemas, handles serialization/deserialization and provides an integration mechanism. -
swagger-jaxrs2
: resolves JAX-RS (annotated) resources into an OpenAPI definition, and provides an integration mechanism. -
swagger-annotations
: a set of annotations to declare and manipultate output generated byswagger-core
,swagger-jaxrs2
and/or other projects. -
swagger-maven-plugin
(since 2.0.5): provides a maven plugin to resolve an OpenAPI definition at build time (usingswagger-jaxrs2
). Please see module readme -
swagger-gradle-plugin
(since 2.0.5): provides a gradle plugin to resolve an OpenAPI definition at build time (usingswagger-jaxrs2
). Please see module readme
One of the common usage scenarios is to integrate swagger-jaxrs2
into an existing or new JAX-RS based project ("code-first"),
to automatically provide and expose its APIs definition, which is kept in sync during the project lifecycle.
Such definition can be the base for further processing/consumption, including API documentation
(e.g with swagger-ui, API client generation in various languages
(e.g with swagger-codegen), custom processing, and so on.
Such result is achieved by scanning JAX-RS resources and resolving their operations and used types, (also) processing applied annotations (e.g. Swagger, JAX-RS, Jackson, JAXB, etc.). An extension mechanism allows to further customize and pre/post processing result.
Check out Quick start below, or jump to Integration and configuration.
Note: Quick start and related sections detail the steps needed to integrate swagger at runtime; since version 2.0.5, swagger-core
project also provides maven and gradle plugins to resolve an OpenAPI definition at build time. As these are based on the same resolving and configuration mechanisms, most information in the wiki applies also in this case.
Swagger uses maven for build and deployment and its artifacts are available at Maven Central. You can use the maven dependencies with any dependency management system that supports maven dependencies such as Maven, Ivy and Gradle. If you're not using Maven, please refer to Not using Maven
Integrating swagger-core
into a JAX-RS application can be as easy as adding its dependency to the project POM:
<dependencies>
...
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2-servlet-initializer</artifactId>
<version>2.2.7</version>
</dependency>
</dependencies>
or since version 2.1.2
better (see #3412):
<dependencies>
...
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2-servlet-initializer-v2</artifactId>
<version>2.2.7</version>
</dependency>
</dependencies>
Consider a simple scenario, consisting in a JAX-RS application (e.g. Jersey or RESTEasy) with a resource like:
@Path("/pet")
@Produces({"application/json", "application/xml"})
public class PetResource {
@GET
@Path("/{petId}")
public Pet getPetById(@PathParam("petId") Long petId) throws io.swagger.sample.exception.NotFoundException {
// return pet
return new Pet();
}
@POST
@Consumes("application/json")
public Response addPet(
@Parameter(description = "Pet object that needs to be added to the store", required = true) Pet pet) {
// add pet
return Response.ok().entity("SUCCESS").build();
}
}
and related model POJO:
@XmlRootElement(name = "Pet")
public class Pet {
private long id;
private String name;
private List<Tag> tags = new ArrayList<Tag>();
@XmlElement(name = "id")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElementWrapper(name = "tags")
@XmlElement(name = "tag")
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
}
Just by adding the dependencies, an endpoint <server_url>/<application_path>/openapi.json
(and openapi.yaml
) is activated,
exposing the OpenAPI definition of the app APIs serialized as json or yaml, as resolved by swagger-core
processing JAX-RS resources defined in the application.
NOTE: The endpoint is fully configurable and/or the definition endpoint can be provided by application defined resources. See Integration and configuration
Given the resource above, the resolved spec looks like:
openapi: 3.0.1
paths:
/sample/pet/{petId}:
get:
operationId: getPetById
parameters:
- name: petId
in: path
required: true
schema:
type: integer
format: int64
responses:
default:
description: default response
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
/sample/pet:
post:
operationId: addPet
requestBody:
description: Pet object that needs to be added to the store
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
required: true
responses:
default:
description: default response
content:
application/json: {}
application/xml: {}
components:
schemas:
Tag:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: Tag
Pet:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
tags:
type: array
xml:
wrapped: true
items:
$ref: '#/components/schemas/Tag'
xml:
name: Pet
In this case resources are identified and provided to swagger-core
engine by the swagger-jaxrs2-servlet-initializer
; there are however
several scenarios in which the dependency to swagger-jaxrs2-servlet-initializer
(or swagger-jaxrs2-servlet-initializer-v2
, see above) is not necessary, as Swagger integration mechanism is capable
of identifying resources from the ones configured by the JAX-RS environment, even without swagger specific settings (e.g. Application.getClasses()
, resourcePackages
Jersey init parameter, and more.
For example, adding io.swagger.v3.jaxrs2.integration.resources
to Jersey 2 container servlet/filter jersey.config.server.provider.packages
init param is by itself sufficient to integrate Swagger and have it scan and expose resolved spec. (in servlet-context-path/openapi.json
or servlet-context-path/openapi.yaml
).
Refer to Dependencies and Exposing OpenAPI definition for more details.
Resources configuration however, along with other init/config settings are fully configurable, see below and Integration and configuration.
Try it out by cloning/downloading the
Jersey or
RESTEasy sample,
and running it with mvn package jetty:run
OpenAPI definition will be available at http://localhost:8002/sample/openapi.yaml
(and .json
).
Not too bad so far, at this point we have a dynamic always-in-sync OpenAPI definition matching our application APIs, basically with zero code changes.
From here we might further customize our result by:
- Providing your own configuration (e.g resource packages/classes, output settings, etc.)
- Taking full control of your API definition (using Swagger annotations)
Or you can allow anyone — be it your development team or your end consumers — to visualize and interact with the API’s resources without having any of the implementation logic in place, using swagger-ui.
Skip to Integration and configuration for full configuration details and integration scenarios.
There are several ways to provide configuration; probably the easiest and least intrusive way is
adding a yaml (or json) file named openapi.yaml
or openapi-configuration.yaml
to the classpath of your application (location and path are flexible and configurable), e.g.
resourcePackages:
- io.swagger.sample.resource
prettyPrint: true
cacheTTL: 0
openAPI:
info:
version: '1.0'
title: Swagger Pet Sample App Config File
description: 'This is a sample server Petstore server. You can find out more
about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net,
#swagger](http://swagger.io/irc/). For this sample, you can use the api key
`special-key` to test the authorization filters.'
termsOfService: http://swagger.io/terms/
contact:
email: [email protected]
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
In the example above, we are providing the packages to be considered while resolving the definition
(resourcePackages
), we declare we want a pretty printed output (prettyPrint
), we disable the cache to
resolve the definition each time the endpoint is hit (cacheTTL
), and we provide an info section directly in
OpenAPI format, which will be merged with the resolved definition (openAPI
).
In this case, as we are providing resourcePackages
ourselves, there is no need to include the initializer
dependency,
therefore a single dependency on swagger-jaxrs2
is sufficient:
<dependencies>
...
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
Try it out by cloning/downloading the
Jersey or
RESTEasy sample,
and running it with mvn package jetty:run
OpenAPI definition will be available at http://localhost:8002/sample/openapi.yaml
(and .json
).
Full description of configuration properties is available here
While Swagger resolver mechanism is able to analyze resource classes structure and various annotations
(e.g JAX-RS, Jackson, etc.) there are cases where metadata is simply not available (for example determining
the response schema of an operation, when the resource method is returning an instance
of JAX-RS Response
instead of a model POJO) and/or we want to completely customize the definition.
To handle this and other cases, and to be able to have full control over the resolved API definition, usage of Swagger annotations comes handy. Further customization can also be achieved by extension mechanisms.
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.
Let's slightly modify our simple resource:
@Path("/pet")
@Produces({"application/json", "application/xml"})
public class PetResource {
static PetData petData = new PetData();
@GET
@Path("/{petId}")
@Operation(summary = "Find pet by ID",
tags = {"pets"},
description = "Returns a pet when 0 < ID <= 10. ID > 10 or nonintegers will simulate API error conditions",
responses = {
@ApiResponse(description = "The pet", content = @Content(
schema = @Schema(implementation = Pet.class)
)),
@ApiResponse(responseCode = "400", description = "Invalid ID supplied"),
@ApiResponse(responseCode = "404", description = "Pet not found")
})
public Response getPetById(
@Parameter(
description = "ID of pet that needs to be fetched",
schema = @Schema(
type = "integer",
format = "int64",
description = "param ID of pet that needs to be fetched",
allowableValues = {"1","2","3"}
),
required = true)
@PathParam("petId") Long petId) throws io.swagger.sample.exception.NotFoundException {
Pet pet = petData.getPetById(petId);
if (null != pet) {
return Response.ok().entity(pet).build();
} else {
throw new io.swagger.sample.exception.NotFoundException(404, "Pet not found");
}
}
}
Here we explicitly declare responses for the operation, using @ApiResponse annotation; additionally we define operation tags and description and we provide a custom schema for a parameter.
The updated definition looks like:
...
paths:
/sample/pet/{petId}:
get:
tags:
- pets
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: petId
in: path
description: ID of pet that needs to be fetched
required: true
schema:
type: integer
description: param ID of pet that needs to be fetched
format: int64
enum:
- 1
- 2
- 3
responses:
default:
description: The pet
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
400:
description: Invalid ID supplied
404:
description: Pet not found
...
We have been able to define a set of responses for the operation and customize a parameter schema, by adding related annotations. Annotations can be applied to resource classes and whatever model POJOs (particularly used in this context is the @Schema annotation).
Try it out by cloning/downloading the
Jersey or
RESTEasy sample,
and running it with mvn package jetty:run
OpenAPI definition will be available at http://localhost:8002/sample/openapi.yaml
(and .json
).
A Petstore sample exemplifies usage of all annotations
Full description of Swagger annotations is available here
Once an API definition is available, you might want to visualize it in a nice UI, and interact with it, for example
testing the endpoint with an actual call. Such functionality is provided by swagger-ui which is nicely integratable with swagger-core
You can see how integration works by cloning/downloading the
Jersey or
RESTEasy sample (or most of samples),
and running it with mvn package jetty:run
Swagger UI will be available at http://localhost:8002
.
The relevant code is the index.html file which makes use of swagger-ui
bundle, downloaded and copied to resources in pom.xml:
(while sample code downloades a new version from master report at every build, you can use whatever mechanism to obtain the bundle)
For further scenarios, documentation and samples, check out Integration and configuration.
OpenAPI 3.1 support details OAS 3.1 support in Swagger Core and Swagger Parser