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.
ComponentThis 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.
ApplicationApplicationInstanceThis 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>