API documentation with OpenAPI

MicroProfile OpenAPI helps you to generate structured documentation from your Jakarta RESTful Services or JAX-RS applications. This documentation helps other microservices and developers to understand and communicate with your application.

Other developers need relevant information to build an application that communicates with the REST API of your application. MicroProfile OpenAPI facilitates this communication by generating human and machine-readable documentation on a simple interface that does not require access to the source code.

The following sections provide more information about the available approaches, supported versions, and configurations for using MicroProfile OpenAPI with Open Liberty.

You can implement MicroProfile OpenAPI for Open Liberty by enabling the MicroProfile OpenAPI feature. When this feature is enabled, you can view the OpenAPI document in a browser by using the /openapi endpoint. For example, if your browser is on the same machine where your server is running, you can view the raw OpenAPI document at the http://localhost:9080/openapi URL or view the OpenAPI document in a user interface at the http://localhost:9080/openapi/ui URL.

To explore how to document and filter RESTful APIs from code or static files by using Open Liberty and MicroProfile OpenAPI, see the Documenting RESTful APIs guide.

The two main approaches to generate an OpenAPI document are the code-first approach and the design-first approach. In the code-first approach, you can generate documentation of the REST API from the source code. The reference document that is produced lists all the API endpoints with descriptions of how to use them. Alternatively, in the design-first approach, you can include a pre-generated OpenAPI document that was written separately from the code. The JAX-RS framework handles basic API generation for JAX-RS annotations and generates a skeleton OpenAPI treemap. You can use this treemap as a starting point and augment it with annotations and code to produce a complete OpenAPI document. Additionally, you can use this manually created documentation to generate stubs, or testable versions of code modules, such as client libraries for the API.

The code-first approach

In the code-first approach, you can initially generate basic API documentation of the REST API from annotations that are specified in the source code. Then, you can augment the existing annotations with OpenAPI annotations, which are processed to generate the documentation. Adding annotations takes less work than manually defining the OpenAPI document, and gives a useful explanation of the different parts of the API.

In the following example, the OpenAPI annotations @APIResponses, @Operation, and @Parameter are added to the purchaseCar() JAX-RS method.

@PUT
 @Path("/buy/{registration}")
 @Produces(MediaType.APPLICATION_JSON)
 @Consumes(MediaType.TEXT_PLAIN)
 @APIResponses(
         value = {
             @APIResponse(
                 responseCode = "404",
                 description = "The requested car could not be found at the dealership, and could not be purchased.",
                 content = @Content(mediaType = "text/plain")),
             @APIResponse(
                 responseCode = "200",
                 description = "The requested car was successfully purchased.",
                 content = @Content(mediaType = "application/json"))})
     @Operation(
         summary = "Purchases the specified car from the dealership, and adds the car to your garage.",
         description = "Retrieves the car with the specified registration from the dealership if it exists, and
                        adds this to the caller's garage. The boolean response represents the state of the internal operation.")
 public Response purchaseCar(
    @Parameter(
              description = "The registration of the car to be added to the inventory.",
              required = true,
              example = "NX15 9012",
              schema = @Schema(type = SchemaType.STRING))
    @PathParam("registration") String registration) {
  boolean success = manager.purchaseCar(registration);
     if (!success) {
         return Response.status(Response.Status.NOT_FOUND)
                        .entity("{ \"error\" : "
                                + "\"The car with registration " + registration
                                + " could not be added to the inventory\" }")
                        .build();
     }
     return Response.ok(success).build();
 }

The default format of the generated document is YAML, but documents can also be provided in JSON format. The following OpenAPI document is generated in YAML format from the OpenAPI annotations in the previous example.

/my-garage/buy/{registration}:
   put:
     summary: "Purchases the specified car from the dealership, and adds the car\
       \ to your garage."
     description: "Retrieves the car with the specified registration from the dealership\
       \ if it exists, and adds this to the caller's garage. The boolean response\
       \ represents the state of the internal operation."
     parameters:
     - name: registration
       in: path
       description: The registration of the car to be added to the inventory.
       required: true
       schema:
         type: string
       example: NX15 9012
     responses:
       "404":
         description: "The requested car could not be found at the dealership, and\
           \ could not be purchased."
         content:
           text/plain: {}
       "200":
         description: The requested car was successfully purchased.
         content:
           application/json: {}

The information that is provided through the OpenAPI annotations augments the basic API documentation that is generated by the JAX-RS framework.

For more information, see the MicroProfile OpenAPI Javadoc for the available annotations.

The design-first approach

An alternative approach is to design the REST API in an editor, such as the Swagger editor before you write any code. With this approach, you can spot and rectify any issues in the design before it is implemented. In large companies, subject matter experts review the API to ensure that it is consistent and usable. The API design then serves as a contract and must be implemented.

You can write this API design in YAML or JSON format and place it in the META-INF directory of your application. Optionally, you can create stubs for the API code. The code-first and design-first approaches are not mutually exclusive. You can augment manually created API documents by adding annotations to the code as you would in a code-first approach.

For more information, see Using pregenerated OpenAPI documents.

Supported OpenAPI versions

The MicroProfile OpenAPI feature generates structured documentation based on the OpenAPI specification. Each new version of the OpenAPI specification updates the documentation format, and different versions of MicroProfile OpenAPI support different OpenAPI specification versions.

Supported OpenAPI versions
FeatureOpenAPI versions supported

mpOpenAPI-4.0

3.1, 3.0

mpOpenAPI-3.1 and earlier

3.0

If you are using a feature that supports more than one version of the OpenAPI specification, you can switch between versions with configuration. You might need to do this if you or your end users use tools or libraries that don’t yet support a newer version of the OpenAPI specification. For more information, see Selecting the OpenAPI specification version.

Multiple application and multi-module application support with MicroProfile OpenAPI

When multiple applications or an application with more than one web module are deployed to the same Open Liberty runtime, the structured documentation differs depending on which MicroProfile OpenAPI feature version you use.

Multiple application and multi-module application support with MicroProfile OpenAPI
FeatureDefault behavior

mpOpenAPI-4.0

All deployed applications and modules are included in the structured documentation. You can modify this behavior through configuration.

mpOpenAPI-2.0 to mpOpenAPI-3.1

Only the first web module of the first deployed application is included in the structured documentation. You can modify this behavior through configuration.

mpOpenAPI-1.0 to mpOpenAPI-1.1

Only the first web module of the first deployed application is included in the structured documentation. This behavior cannot be modified.

Including and excluding applications and modules from OpenAPI documentation

You can configure which applications or modules are included in your OpenAPI documentation either by setting elements in your server.xml file or by specifying MicroProfile Config properties. For most scenarios, server.xml configuration is preferred and MicroProfile Config properties are recommended only for compatibility with existing configurations that are already using these properties.

Configure application or module documentation by using the server.xml file

You can control the inclusion and exclusion of applications and modules in the OpenAPI documentation by configuring the following elements within the mpOpenAPI configuration element in your server.xml file:

  • excludeModule | excludeApplication: Specify module or application names, one per element, that are to be excluded from the OpenAPI document. Specify module names in the {ApplicationName}/{ModuleName} format.

  • includeModule | includeApplication: Specify module or application names, one per element, that are to be included in the OpenAPI document. Specify module names in the {ApplicationName}/{ModuleName} format. The all special value includes all available applications.

  • info: Specify an info section for the OpenAPI document. This element is useful to override the default info section of merged OpenAPI documentation for multiple modules or applications.

In MicroProfile OpenAPI 4.0 and later, all applications and modules are included by default. To exclude certain applications or modules, specify the excludeModule or excludeApplication element within the mpOpenAPI element.

In the following example, the sample_app application consists of an EAR file containing five web modules. This configuration excludes modules 3 and 5 and provides a custom info section for the merged API documentation for modules 1, 2, and 4:

<mpOpenAPI>
  <excludeModule>sample_app/module-3</excludeModule>
  <excludeModule>sample_app/module-5</excludeModule>
  <info title="A multi-module sample application"
        description="This is a sample application."
        version="2.0.1"
        termsOfService="http://example.com/sample_app/terms"
        contactName="API Support"
        contactUrl="http://www.example.com/sample_app/support"
        contactEmail="[email protected]"
        licenseName="License 2.0"
        licenseUrl="https://www.example.org/licenses/LICENSE-2.0.html"
        />
</mpOpenAPI>

In MicroProfile MicroProfile OpenAPI 2.0 - 3.1, only the first web module of the first deployed application is included in the structured documentation. To include or exclude applications, specify the corresponding elements within the mpOpenAPI element.

In the following example, the sample_app application consists of an EAR file containing five web modules. By default, only module-1 is included in the documentation. This configuration includes all modules, then selectively excludes modules 3 and 5. It also provides a custom info section for the merged API documentation for modules 1, 2, and 4:

<mpOpenAPI>
  <includeApplication>all</includeApplication>
  <excludeModule>sample_app/module-3</excludeModule>
  <excludeModule>sample_app/module-5</excludeModule>
  <info title="A multi-module sample application"
        description="This is a sample application."
        version="2.0.1"
        termsOfService="http://example.com/sample_app/terms"
        contactName="API Support"
        contactUrl="http://www.example.com/sample_app/support"
        contactEmail="[email protected]"
        licenseName="License 2.0"
        licenseUrl="https://www.example.org/licenses/LICENSE-2.0.html"
        />
</mpOpenAPI>

When you configure OpenAPI documentation in the server.xml file, the application name is determined by the value of the name attribute when the application is deployed in server.xml using application, webApplication, or enterpriseApplication. For example:

<webApplication name="application1" location="application1-v1.war" />

If the application is deployed in the dropins directory or if the name attribute is not specified, the name defaults to the archive filename without the file extension.

For module names, the module name is specified in the web module’s web.xml file. If no web.xml file exists or if it does not specify a name, the module name defaults to the file name without the file extension.

Configure application or module documentation by using MicroProfile Config properties

MicroProfile Config provides properties to manage which applications and modules are included in the generated OpenAPI documentation. This option is recommended only for compatibility with applications that already use MicroProfile Config to include or exclude modules or applications fro the API documentation. Newer configurations can instead use the server.xml file, as previously described.

When you configure the inclusion or exclusion of modules or applications with MicroProfile Config, the following limitations apply:

  • You must configure properties in a source that applies to the entire runtime, such as the bootstrap.properties, jvm.properties, or server.env files, or the variable element in the server.xml file.

  • Any configuration that is defined in the server.xml file to include or exclude modules and applications takes precedence over configuration that is set through MicroProfile Config.

The following table lists MicroProfile Config properties that can be specified to configure which modules or applications are included in the generated OpenAPI documentation.

Configuration properties for multiple application and multi-module application support
Property nameDescriptionValid values

mp.openapi.extensions.liberty.merged.include

This property specifies which modules or applications are included in the generated OpenAPI documentation.

  • all
    This value includes all modules and applications in a deployment.

  • first
    This value includes only the first web module of the first application deployed.

  • A comma-separated list of application_name or application_name/module_name includes the named applications and modules.

mp.openapi.extensions.liberty.merged.exclude

This property overrides the mp.openapi.extensions.liberty.merged.include property to specify which applications or web modules are excluded from the generated OpenAPI documentation.

  • none
    This value excludes no applications or web modules.

  • A comma-separated list of application_name or application_name/module_name excludes the named applications and modules.

mp.openapi.extensions.liberty.merged.info

This property sets the info section of the final Open API document. If it is set, the info section in the final OpenAPI document is replaced with the value of the property. This replacement is made after any merging is completed.

The value must be a valid OpenAPI info section in JSON format.

In the following jvm.properties file example, an OpenAPI document is configured for the sample_app application, which consists of an EAR file with five web modules.

mp.openapi.extensions.liberty.merged.include=all
mp.openapi.extensions.liberty.merged.exclude=sample_app/module-3,sample_app/module-5
mp.openapi.extensions.liberty.merged.info=
{
  "title": "A multi-module sample application",
  "description": "This is a sample application.",
  "termsOfService": "http://example.com/sample_app/terms",
  "contact": {
    "name": "API Support",
    "url": "http://www.example.com/sample_app/support",
    "email": "[email protected]"
  },
  "license": {
    "name": "License 2.0",
    "url": "https://www.example.org/licenses/LICENSE-2.0.html"
  },
  "version": "2.0.1"
}
  • The mp.openapi.extensions.liberty.merged.include property specifies that all five modules are included in the final OpenAPI document.

  • The mp.openapi.extensions.liberty.merged.exclude overrides the mp.openapi.extensions.liberty.merged.include property to exclude the module-3 and module-5 web modules.

  • The mp.openapi.extensions.liberty.merged.info property sets the info section for the final OpenAPI document, which documents web modules 1, 2, and 4.

When you configure support for multiple applications and multi-module environments by using MicroProfile Config, the application name is determined from the application’s deployment descriptor (application.xml or web.xml). If the deployment descriptor is missing or does not specify a name, the application name defaults to the application archive file name without the file extension. Similarly, the module name is specified in the web module web.xml file. If the web.xml file does not exist or does not specify a name, the module name defaults to the file name without the file extension.