adam bien's blog

Generating Swagger / OpenAPI Without External Dependencies 📎

A CRUD JAX-RS 2 (Java EE 7/8) service:


@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("workshops")
public class WorkshopsResource {

    @GET
    public JsonArray all() {
        return Json.createArrayBuilder().
                add("java").
                add("web").
                build();
    }

    @GET
    @Path("{name}")
    public JsonObject get(@PathParam("name") String name) {
        return null;
    }

    @PUT
    @Path("{name}")
    public void add(@PathParam("name") String name, JsonObject workshop) {

    }

    @DELETE
    @Path("{name}")
    public void remove(@PathParam("name") String name) {

    }
}    

...deployed on MicroProfile compatible application servers (tested with Payara Server 5 Full Profile), emits the following OpenAPI/swagger document from the standardized uri: http://localhost:8080/openapi:


openapi: 3.0.0
info:
    title: Deployed Resources
    version: 1.0.0
servers:
- url: http://localhost:8080/openapi-sample
    description: Default Server.
paths:
    /resources/workshops:
    get:
        operationId: all
        responses:
        default:
            description: Default Response.
            content:
            application/json:
                schema:
                type: object
    /resources/workshops/{name}:
    get:
        operationId: get
        parameters:
        - name: name
        in: path
        required: true
        style: simple
        schema:
            type: string
        responses:
        default:
            description: Default Response.
            content:
            application/json:
                schema:
                type: object
    put:
        operationId: add
        parameters:
        - name: name
        in: path
        required: true
        style: simple
        schema:
            type: string
        requestBody:
        content:
            application/json:
            schema:
                type: object
        responses:
        default:
            description: Default Response.
            content:
            application/json:
                schema:
                type: object
    delete:
        operationId: remove
        parameters:
        - name: name
        in: path
        required: true
        style: simple
        schema:
            type: string
        responses:
        default:
            description: Default Response.
            content:
            application/json:
                schema:
                type: object
components: {}

For the creation of the document above, no additional dependencies, configuration or changes were needed. The example above is a 3.9kB Thin WAR.

Because servers like Payara Server 5 Full Profile or OpenLiberty support Java EE 8 and MicroProfile at the same time, you neither have to change your runtime, nor your lean Java EE 8 build setup:


<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.airhacks</groupId>
<artifactId>openapi-sample</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
   <dependency>
       <groupId>javax</groupId>
       <artifactId>javaee-api</artifactId>
       <version>8.0</version>
       <scope>provided</scope>
   </dependency>
</dependencies>
<build>
   <finalName>openapi-sample</finalName>
</build>
<properties>
   <maven.compiler.source>1.8</maven.compiler.source>
   <maven.compiler.target>1.8</maven.compiler.target>
   <failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
</project>    
For customizations (coming with the MicroProfile OpenAPI) you will need a single provided dependency to the MicroProfile API:

<dependency>
    <groupId>org.eclipse.microprofile</groupId>
    <artifactId>microprofile</artifactId>
    <version>1.3</version>
    <type>pom</type>
    <scope>provided</scope>
</dependency>	    

Enjoy Java EE 8 + MicroProfile and stay light!

See you at MicroProfile With or Without Jakarta EE, at Munich Airport, Terminal 2