Getting started with OpenAPI on WildFly

The Microprofile OpenAPI can be used to document your REST endpoint using annotations or a pre-generated JSON in a standard way. In this tutorial we will learn how to leverage this API on applications deployed on WildFly.

Documenting REST Services is extremely useful since, as it follows a standard, it can be used in a range of tools such as those provided by the Swagger suite. These tools let you do all sorts of things such as design, edit and test a REST API documented by an OpenAPI document. Documents generated with OpenAPI typically contain:

  • A list of common objects
  • A list of servers the API is available from
  • A list of each path in the API as well as what parameters it accepts

Here is a sample application which documents the org.eclipse.microprofile.openapi.annotations.responses.APIResponse for a set of org.eclipse.microprofile.openapi.annotations.Operation:

package com.itbuzzpress.microprofile.service;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.container.*;
import javax.ws.rs.core.*;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import com.itbuzzpress.microprofile.model.SimpleProperty;
@Tag(name = "OpenAPI Example", description = "Get a text in various formats")

@Path("/simple")
public class SimpleRESTService {
	@GET
	@Operation(description = "Getting Hello Text")
	@APIResponse(responseCode = "200", description = "Successful, Text")
	@Path("/text")
	public String getHello () 
	{
		return "hello world!";
	}

	@GET
	@Operation(description = "Getting Hello JSON")
	@APIResponse(responseCode = "500", description = "Error in generating JSON")
	@Path("/json")
	@Produces(MediaType.APPLICATION_JSON)
	public SimpleProperty getPropertyJSON () 
	{
        SimpleProperty p = new SimpleProperty("key","value");
		return p;
	}
	@GET
	@Path("/xml")
	@Operation(description = "Getting Hello XML")
	@APIResponse(responseCode = "200", description = "Successful, return XML")
	@Produces(MediaType.APPLICATION_XML)
	public SimpleProperty getPropertyXML () 
	{
        SimpleProperty p = new SimpleProperty("key","value");
		return p;
	}
}

This class also includes a org.eclipse.microprofile.openapi.annotations.tags.Tag annotation that stores some meta-information you can use to help organize your API endpoints.

In order to build this class, you will need the microprofile-openapi dependency in your pom.xml

<dependency>
    <groupId>org.eclipse.microprofile.openapi</groupId>
    <artifactId>microprofile-openapi-api</artifactId>
</dependency>

Before deploying the example, check if the openapi extension is included in your configuration file:

[standalone@localhost:9990 /] /extension=org.wildfly.extension.microprofile.  [TAB]
org.wildfly.extension.microprofile.config-smallrye           org.wildfly.extension.microprofile.metrics-smallrye
org.wildfly.extension.microprofile.fault-tolerance-smallrye  org.wildfly.extension.microprofile.health-smallrye           
org.wildfly.extension.microprofile.opentracing-smallrye      org.wildfly.extension.microprofile.jwt-smallrye  

In the current release (WIldFly 19) it is not included in the default profile, so you have two main options here:

Option 1) Start WildFly using a Microprofile profile such as:

$ ./standalone -c standalone-microprofile.xml

Option 2) Activate the openapi-smallrye extension and subsystem in your server profile as follows:

[standalone@localhost:9990 /]  /extension=org.wildfly.extension.microprofile.openapi-smallrye:add()
{"outcome" => "success"}

Next, add its subsystem:

[standalone@localhost:9990 /] /subsystem=microprofile-openapi-smallrye:add()
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}

Here is a sample json that is generated through the openapi context:

$ curl -v http://localhost:8080/openapi

And this is the description of the endpoint generated through the OpenAPI:

openapi: 3.0.1
info:
  title: Generated API
  version: "1.0"
tags:
- name: OpenAPI Example
  description: Get a text in various formats
paths:
  /rest/simple/json:
    get:
      tags:
      - OpenAPI Example
      description: Getting Hello JSON
      responses:
        200:
          description: Successful, return JSON
  /rest/simple/text:
    get:
      tags:
      - OpenAPI Example
      description: Getting Hello Text
      responses:
        200:
          description: Successful, Text
  /rest/simple/xml:
    get:
      tags:
      - OpenAPI Example
      description: Getting Hello XML
      responses:
        200:
          description: Successful, return XML

If you prefer, you can also have the endoint description in JSON format by appending the format parameter:

$ curl -v http://localhost:8080/openapi?format=JSON  

Please note that on some browsers you might get a “406 – Not Acceptable error” if you try to access the openapi URI (http://localhost:8080/openapi). In this case, just request it using cURL as in the above example.

This tutorial is an excerpt from the book “Practical Enterprise Development” available on ItBuzzPress:

Source code for this tutorial available here: https://bit.ly/39o9nkL

Found the article helpful? if so please follow us on Socials