back to all blogsSee all blog posts

Building Better APIs: Documenting APIs in Open Liberty using MicroProfile OpenAPI

image of author image of author
Sweetty P Devassy and Abhinav K on Apr 28, 2025
Post available in languages:

As technology has evolved and our applications have become more complicated, so too have our APIs. We are now building a huge number of highly complicated APIs. Documenting them requires effort and is often seen as a tedious task. Furthermore, the complex nature of these APIs can make documentation even more challenging. But why does documentation of our APIs matter? API documentation serves as a means of sharing up-to-date information between development teams, acting as a sort of how-to manual for developers that are looking to build things with your API. But having a standardized way of documenting our APIs so that we can all easily understand other APIs and what they do was a challenge…​ at least until the development of Swagger and later the OpenAPI specification. Having a structured approach to documentation helps developers improve collaboration, reduce errors, and accelerate development cycles.

So, let’s dive into the OpenAPI specification and explore how you can use it in your Open Liberty project with MicroProfile OpenAPI features to easily and effectively document your APIs.

What is OpenAPI?

OpenAPI is a standardised specification for describing RESTful APIs in a machine-readable format (JSON or YAML). It allows developers to define, document, and share API structures in a way that is both human-readable and programmatically useful. At its core, an OpenAPI definition includes:

  • Info – API title, version, description

  • Servers – Base URLs of the API

  • Paths – Endpoints (/users, /orders)

  • Methods – GET, POST, PUT, DELETE

  • Parameters – Query, path, header, or body inputs

  • Responses – Expected status codes and return data

  • Security – Authentication methods (OAuth, API keys, etc.)

The OpenAPI specification can be used together with Swagger UI to allow developers to visualize the APIs and test them interactively. The great part about this integration is that the UI is automatically generated from your OpenAPI specification.

MicroProfile OpenAPI and Open Liberty

For Open Liberty developers, the MicroProfile OpenAPI library can be used to integrate and make use of the OpenAPI specification. As well as enabling the documentation standards offered through the OpenAPI specification, MicroProfile OpenAPI also eliminates some of the need for additional manual effort by offering the ability to automatically generate OpenAPI-compliant documentation for JAX-RS services, saving even more time and effort! Making use of MicroProfile OpenAPI, Open Liberty developers are able to maintain consistent, accurate, and up-to-date API documentation.

Additionally, MicroProfile OpenAPI can be used seamlessly with the Swagger UI to enhance the developer and user experience by providing interactive API documentation, allowing users to visualise endpoints, test API calls, and understand request/response structures in a more intuitive way. This removes the need for manually written API documentation, reducing maintenance overhead and minimising the risk of outdated or inconsistent documentation.

In summary, MicroProfile OpenAPI streamlines API development in Open Liberty, making it easier for teams to build, expose, and manage RESTful services efficiently.

Adding MicroProfile OpenAPI to Open Liberty

  1. Set up Java

    • Install JDK 8 or later.

    • Set the JAVA_HOME environment variable.

      • Linux/macOS: export JAVA_HOME=/path/to/jdk

      • Windows: set JAVA_HOME=C:\path\to\jdk

  2. Download a sample Open Liberty Project

  3. Extract the files

    • Extract the downloaded .zip file to your preferred directory.

  4. Add MicroProfile dependency in pom.xml

    Copied to clipboard
    <dependency>
        <groupId>org.eclipse.microprofile</groupId>
        <artifactId>microprofile</artifactId>
        <version>7.0</version>
        <type>pom</type>
        <scope>provided</scope>
    </dependency>
  5. Update server.xml in liberty/config to enable MicroProfile: (microprofile-7.0 includes mpOpenAPI-4.0 feature)

    Copied to clipboard
    <featureManager>
        <feature>jakartaee-10.0</feature>
        <feature>microprofile-7.0</feature>
    </featureManager>
  6. Create an Endpoints.java file,

    • Define your API endpoints and add MicroProfile OpenAPI annotations. For example:

      Copied to clipboard
      import org.eclipse.microprofile.openapi.annotations.Operation;
      import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
      import jakarta.ws.rs.GET;
      import jakarta.ws.rs.Path;
      import jakarta.ws.rs.Produces;
      import jakarta.ws.rs.core.MediaType;
      
      @Path("/hello")
      public class Endpoints {
      
          @GET
          @Produces(MediaType.TEXT_PLAIN)
          @Operation(summary = "Returns a greeting message")
          @APIResponse(responseCode = "200", description = "Successful response")
          public String hello() {
              return "Hello, OpenAPI with Liberty!";
          }
      }
  7. Run the project using Maven

    • Execute: mvn liberty:dev

  8. Test using Swagger UI

For a fully functional example, check out this GitHub Repository. This blog will use this example project for further explanations.

This is how it appears on the Swagger UI

Swagger UI

MicroProfile OpenAPI Annotations

MicroProfile OpenAPI provides the following annotations:

Table 1. MicroProfile OpenAPI Annotations
Annotation Purpose

@OpenAPIDefinition

Defines API metadata like title, version, description, and contact details.

@Info

Provides API information (title, version, description, contact, license).

@Server

Specifies the server where the API is hosted.

@Tag

Categorises API operations into different groups.

@Operation

Describes an API endpoint operation.

@APIResponse

Defines responses for an API operation.

@APIResponses

Groups multiple @APIResponse annotations.

@Parameter

Defines a parameter in an API request.

@SecurityRequirement

Specifies security requirements for an endpoint.

@Schema

Defines the structure of request and response models.

Below is an example of using MicroProfile OpenAPI annotations to define an API, its metadata, security, and operations.

1 . API Metadata Definitions

These annotations should used with a REST Application class.

  • @OpenAPIDefinition - Defines metadata for the entire API.

  • @Info - Provides metadata such as title, description, version, and contact details.

  • @Server - Specifies one or more servers where the API is hosted.

  • @Tag - Defines logical groupings of endpoints.

  • @SecurityRequirement - Documentation for security (e.g., JWT authentication) of API endpoints.

Copied to clipboard
@OpenAPIDefinition(
    info = @Info(
        title = "Blog API",
        version = "1.0",
        description = "This is an example API using MicroProfile OpenAPI",
        contact = @Contact(name = "Sweetty", email = "sweetty@gmail.com"),
        license = @License(name = "Apache 2.0", url = "https://apache.org/licenses/LICENSE-2.0.html")
    ),
    servers = @Server(url = "http://localhost:9080/openapi-demo", description = "Localhost Server"),
    tags = {
        @Tag(name = "Blog", description = "Operations related to blog management")
    },
    security = @SecurityRequirement(name = "jwtAuth")
)
public class Endpoints extends Application {
API Metadata Definitions

2 . Security Definitions

These annotations should used with a REST Application class.

  • @SecurityScheme - Defines authentication for the API.

  • @SecuritySchemes- Specifies multiple security schemes if needed.

Copied to clipboard
@SecuritySchemes({
    @SecurityScheme(
        securitySchemeName = "jwtAuth",
        description = "JWT Authentication",
        type = SecuritySchemeType.HTTP,
        scheme = "bearer",
        bearerFormat = "JWT"
    )
})
public class Endpoints extends Application {
Security Definitions

3 . API Operations

These annotations should be used with REST resource methods.

  • @Operation - Describes an API operation.

  • @APIResponse - Defines possible responses for an operation.

  • @ApiResponses - Groups multiple @APIResponse annotations.

  • @Content - Specifies the media type and structure of request/response bodies.

  • @Schema - Defines the properties of a model used in API requests and responses.

Copied to clipboard
@GET
@Path("/user/{id}")
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = "Blog")
@Operation(summary = "Get User by ID", description = "Returns the user details for a given ID")
@APIResponses({
@APIResponse(responseCode = "200", description = "Successful Response", content = @Content(
    mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = User.class)
)),
@APIResponse(responseCode = "404", description = "User not found")})
public User getUser(
API Operations
API Operations Response

4 . Request Parameter Definitions

This annotation should be used with REST resource method parameters.

  • @Parameter - Describes request parameters.

Copied to clipboard
public User getUser(
        @Parameter(description = "User ID", required = true)
        @PathParam("id") String id) {

    return new User(id, "John Doe");
}
Request Parameter Definitions

5 . Schema Definitions

This annotation should be defined on a Schema class.

  • @Schema at the class level provides metadata for the model.

  • @Schema at the field level describes each property of the model.

Copied to clipboard
@Schema(description = "User model")
class User {
    @Schema(description = "Unique user ID", example = "123")
    public String id;

    @Schema(description = "User name", example = "John Doe")
    public String name;
Schema Definitions

While basic API documentation is automatically generated from REST methods in Open Liberty, MicroProfile OpenAPI annotations help enhance and refine it. This is similar to how Javadoc comments work in Java—without them, Javadoc can still list methods, parameters, and return types, but it lacks detailed explanations of behavior and usage. Likewise, MicroProfile OpenAPI annotations provide essential context to REST endpoints, describing their purpose, expected inputs, responses, and error handling. Additionally, some API details cannot be inferred directly from Java code, such as custom response headers, security requirements, or detailed descriptions of parameters. In such cases, annotations become essential for ensuring comprehensive, well-structured API documentation that is both developer-friendly and machine-readable.

The MicroProfile OpenAPI feature is responsible for generating this documentation. This eliminates the need for external configuration files and ensures the documentation evolves alongside the codebase.

Ultimately, MicroProfile OpenAPI annotations play a vital role in creating useful, up-to-date documentation. Because they reside within the source code, they make it easier for teams to maintain alignment between implementation and documentation—benefiting both developers and end users who need to understand how to interact with the API effectively.

Influence

As API architectures evolve, OpenAPI, the industry-standard specification for documenting REST APIs, is influencing how other tools' and specifications' APIs handle documentation and interoperability. Among those being influenced are GraphQL and gRPC. GraphQL is a query language for your API, and a server-side runtime for executing queries using a type system you define for your data. gRPC is a modern open source high performance Remote Procedure Call (RPC) framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. While OpenAPI was designed for REST, its structured approach to API documentation, tooling, and automation has influenced how GraphQL and gRPC handle documentation and interoperability.

  • OpenAPI’s structured JSON/YAML format has influenced GraphQL’s SDL (Schema Definition Language), where types, queries, and mutations are explicitly defined.

  • Tools like Swagger UI, which originated alongside the Swagger project and now commonly accompany OpenAPI specifications, have inspired similar tools in other ecosystems. For example, gRPC UI offers an interactive interface to explore and test gRPC methods, much like Swagger UI does for REST APIs—though both Swagger UI and gRPC UI are independent, community-driven tools.

Conclusion

In today’s world of microservices and cloud computing, standardised API documentation is more important than ever. OpenAPI has become the foundation for creating consistent, accessible, and well-documented APIs, ensuring seamless integration across diverse systems. As APIs continue to evolve, having a structured approach to documentation helps developers improve collaboration, reduce errors, and accelerate development cycles. For those working with Open Liberty, exploring MicroProfile OpenAPI offers a way to generate OpenAPI-compliant documentation, making API management more efficient. As we embrace automation and interoperability in modern software development, OpenAPI will have an important role to play.

Want to get hands-on with this and try it out in our own Open Liberty applications? Either follow along with our interactive guide, or, check out the documentation we have available too: