Building Better APIs: Documenting APIs in Open Liberty using MicroProfile OpenAPI
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
-
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
-
-
-
Download a sample Open Liberty Project
-
Go to the Open Liberty starter page.
-
Choose the appropriate release and download the
.zip
file.
-
-
Extract the files
-
Extract the downloaded
.zip
file to your preferred directory.
-
-
Add MicroProfile dependency in
pom.xml
<dependency> <groupId>org.eclipse.microprofile</groupId> <artifactId>microprofile</artifactId> <version>7.0</version> <type>pom</type> <scope>provided</scope> </dependency>
-
Update
server.xml
inliberty/config
to enable MicroProfile: (microprofile-7.0
includesmpOpenAPI-4.0
feature)<featureManager> <feature>jakartaee-10.0</feature> <feature>microprofile-7.0</feature> </featureManager>
-
Create an Endpoints.java file,
-
Define your API endpoints and add MicroProfile OpenAPI annotations. For example:
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!"; } }
-
-
Run the project using Maven
-
Execute:
mvn liberty:dev
-
-
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

MicroProfile OpenAPI Annotations
MicroProfile OpenAPI provides the following 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.
@OpenAPIDefinition(
info = @Info(
title = "Blog API",
version = "1.0",
description = "This is an example API using MicroProfile OpenAPI",
contact = @Contact(name = "Sweetty", email = "[email protected]"),
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 {

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.
@SecuritySchemes({
@SecurityScheme(
securitySchemeName = "jwtAuth",
description = "JWT Authentication",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT"
)
})
public class Endpoints extends Application {

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.
@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(


4 . Request Parameter Definitions
This annotation should be used with REST resource method parameters.
-
@Parameter
- Describes request parameters.
public User getUser(
@Parameter(description = "User ID", required = true)
@PathParam("id") String id) {
return new User(id, "John Doe");
}

5 . Schema Definitions
This annotation should be defined on a Schema class.
-
@Schema
at theclass level
provides metadata for the model. -
@Schema
at thefield level
describes each property of the model.
@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;

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: