API Documentation
For documenting REST APIs, we use the Swagger framework to generate up-to-date API documentation directly out of the application at runtime. This ensures that there's always up-to-date API documentation available.
Component
This option enables the expansion of Swagger annotations in the REST API generated using the
enableJaxrs
option. The option will also trigger the integration of
Swagger UI into the application. For every REST Component, a Swagger UI page
will be available at /applicationName/swagger/componentName
. This copy of Swagger UI will automatically load the
API definition from the swagger.json file that is server up by the Swagger library.
<options>
<enableSwagger/>
</options>
OpenAPI
OpenAPI, formerly known as Swagger, is a widely-adopted industry standard for designing, documenting, and consuming RESTful APIs. The default version supported by the REST expanders in OpenAPI 3.0.
Application
ApplicationInstance
This option allows you to select the version of OpenAPI that is used. By default OpenAPI 3.0 is used, but it is possible to switch to OpenAPI 2 (Swagger).
There is experimental support for OpenAPI 3.1 as well, but Swagger UI still lacking support for this version.
<options>
<jaxrs.openapi.version>3.0</jaxrs.openapi.version>
</options>
<options>
<jaxrs.openapi.version>2</jaxrs.openapi.version>
</options>
The API specification for an API component is available in json or yaml format as an endpoint on the application:
- OpenAPI 3.0
- OpenAPI 2 (Swagger)
-
/<applicationName><basePath>/openapi.json
-
/<applicationName><basePath>/openapi.yaml
-
/<applicationName><basePath>/swagger.json
-
/<applicationName><basePath>/swagger.yaml
The basePath
is defined as the value of the enableJaxrs
option.
Annotations
The API documentation is generated mostly based on annotations added into the code of the REST connectors and related classes. The Swagger library extracts information from all technical annotations for Jersey that define the API, as well as additional annotations purely for API documentation.
Connector
We group all endpoints in a connector together in the API definition to clearly indicate that these endpoints are related. Typically, endpoints in a connector are all related to the same DataElement.
- OpenAPI 3.0
- OpenAPI 2 (Swagger)
The @Tag
annotation is added to connector classes to group API endpoints together in the documentation as
part of that connector.
// @anchor:annotations:start
@Tag(name = "MyElement Apis")
// @anchor:annotations:end
// anchor:custom-annotations:start
// anchor:custom-annotations:end
@Path("/myelements")
public final class MyElementConnector { }
If needed, additional @Tag
annotations can be added to the connector (or individual endpoint methods).
The @Api
annotation is added to connector classes to group API endpoints together in the documentation as
part of that connector. The endpoints are grouped under the tag(s) in defined in the tags
property.
// @anchor:annotations:start
@Api(tags = {
"MyElement Apis",
// anchor:custom-api-tags:start
// anchor:custom-api-tags:end
}
// anchor:custom-api:start
// anchor:custom-api:end
)
// @anchor:annotations:end
// anchor:custom-annotations:start
// anchor:custom-annotations:end
@Path("/myelements")
public final class MyElementConnector { }
Endpoints
To document endpoints, we provide a concise description of what the endpoint does in function of the DataElement it relates to. Aside from that we also provide some documentation about the responses that can be returned by that endpoint.
- OpenAPI 3.0
- OpenAPI 2 (Swagger)
The @Operation
annotation is added to an endpoint to provide a brief summary
of the
functionality of the endpoint, as well as a list of possible responses
that can be returned by the
endpoint as @ApiResponse
annotations that list the HTTP responseCode
, a description
for that response and the content
that is returned. The content
is
represented by the @Content
annotation that lists the mediaType
for the response and a schema
,
which links to the implementation
class for that response with a @Schema
annotation.
// @anchor:post-annotations:start
@Operation(
summary = "Create a new MyElement",
responses = {
@ApiResponse(responseCode = "201", description = "Created", content = @Content(
mediaType = "application/json", schema = @Schema(implementation = CreatedResponse.class))),
@ApiResponse(responseCode = "400", description = "Bad request", content = @Content(
mediaType = "application/json", schema = @Schema(implementation = RestErrorResponse.class))),
@ApiResponse(responseCode = "401", description = "Access denied", content = @Content(
mediaType = "application/json", schema = @Schema(implementation = RestErrorResponse.class))),
@ApiResponse(responseCode = "404", description = "Not found", content = @Content(
mediaType = "application/json", schema = @Schema(implementation = RestErrorResponse.class))),
@ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(
mediaType = "application/json", schema = @Schema(implementation = RestErrorResponse.class))),
// anchor:custom-post-apiResponse-annotations:start
// anchor:custom-post-apiResponse-annotations:end
}
// anchor:custom-post-operation:start
// anchor:custom-post-operation:end
)
// @anchor:post-annotations:end
// anchor:custom-post-annotations:start
// anchor:custom-post-annotations:end
@POST
@Consumes(MediaTypes.APPLICATION_JSON)
@Produces({MediaTypes.APPLICATION_JSON, MediaTypes.APPLICATION_PROBLEM_JSON})
public Response createMyElement(...) { }
For endpoints that require the client to send a body, the body parameter of the endpoint is marked using
the @RequestBody
parameter. Since a body is always required for these endpoints which we expand,
the required
property is set to true.
public Response createMyElement(
// @anchor:post-parameters:start
// @anchor:post-parameters:end
// anchor:custom-post-parameters:start
// anchor:custom-post-parameters:end
/*@anchor:post-model-annotations:start@*/@RequestBody(required = true)/*@anchor:post-model-annotations:end@*/ MyElementPostInputModel input,
@Context ContainerRequestContext requestContext
)
The @ApiOperation
annotation is added to an endpoint to provide a brief description (value
property) of the endpoint. The @ApiResponses
annotation defines a set of possible responses that can be
returned by the endpoint as @ApiResponse
annotations that list the HTTP code
, a message
for that response and the response
class that is used to represent that response.
// @anchor:post-annotations:start
@ApiOperation(
value = "Create a new MyElement"
// anchor:custom-post-apiOperation:start
// anchor:custom-post-apiOperation:end
)
@ApiResponses(value = {
@ApiResponse(code = 201, message = "Created", response = CreatedResponse.class),
@ApiResponse(code = 400, message = "Bad request", response = RestErrorResponse.class),
@ApiResponse(code = 401, message = "Access denied", response = RestErrorResponse.class),
@ApiResponse(code = 404, message = "Not found", response = RestErrorResponse.class),
@ApiResponse(code = 500, message = "Internal server error", response = RestErrorResponse.class),
// anchor:custom-post-apiResponse-annotations:start
// anchor:custom-post-apiResponse-annotations:end
})
// @anchor:post-annotations:end
// anchor:custom-post-annotations:start
// anchor:custom-post-annotations:end
@POST
@Consumes(MediaTypes.APPLICATION_JSON)
@Produces({MediaTypes.APPLICATION_JSON, MediaTypes.APPLICATION_PROBLEM_JSON})
public Response createMyElement(...) { }
For endpoints that require the client to send a body, the body parameter of the endpoint is marked using
the @ApiParam
parameter.
public Response createMyElement(
// @anchor:post-parameters:start
// @anchor:post-parameters:end
// anchor:custom-post-parameters:start
// anchor:custom-post-parameters:end
/*@anchor:post-model-annotations:start@*/@ApiParam/*@anchor:post-model-annotations:end@*/ MyElementPostInputModel input,
@Context ContainerRequestContext requestContext
)
Swagger UI
Swagger UI is an open-source tool that we use to visualize our API documentation and interact with APIs resources and methods, to make it easier to understand and test the API.
For each component that defines a REST API, we also provide an endpoint where a Swagger UI interface is available to interact with that API. For all versions of the OpenAPI specification, the Swagger UI interface is available on the same endpoint:
/<applicationName>/swagger/<componentName>