REST Services using Thorntail

IMPORTANT: The Thorntail project (formerly known as WildFly Swarm) has reached End Of Life. The last announced release is the 2.7.0. You are recommended to evaluate a migration plan for your applications. We recommend checking this article that describes how to run REST Services in a WildFly Bootable JAR application: Turn your WildFly application in a Bootable JAR

A practical use case for micro services is to provide access to resources using REST Api. As an example, we will show how to set up a JAX-RS server using Thorntail and adding Swagger UI on the top of it to easily document and consume the available services.

As usual, start by using the Thorntail project generator to create the basic structure of a project: https://thorntail.io/generator/

Within the Thorntail project generator, select the JAX-RS and Swagger dependencies fractions as you can see from the following picture:

thorntail rest example tutorial

The Swagger fraction will generate the swagger.json descriptor for all JAX-RS resources found. The Swagger WebApp will provide an UI for displaying and invoking the services discovered by Swagger. Click “Generate Project” to download the project and open it from your favorite IDE.

Project configuration

As you can see from the pom.xml, the following dependencies have been automatically added so that you can bootstrap a WildFly server with JAX-RS and Swagger fractions:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>demo-rest</artifactId>
  <name>Thorntail Example</name>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <properties>
    <version.thorntail>2.3.0.Final</version.thorntail>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <failOnMissingWebXml>false</failOnMissingWebXml>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.thorntail</groupId>
        <artifactId>bom-all</artifactId>
        <version>${version.thorntail}</version>
        <scope>import</scope>
        <type>pom</type>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <finalName>demo</finalName>
    <plugins>
      <plugin>
        <groupId>io.thorntail</groupId>
        <artifactId>thorntail-maven-plugin</artifactId>
        <version>${version.thorntail}</version>
        
        <executions>
          <execution>
            <goals>
              <goal>package</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    
    <dependency>
      <groupId>io.thorntail</groupId>
      <artifactId>swagger</artifactId>
    </dependency><dependency>
      <groupId>io.thorntail</groupId>
      <artifactId>jaxrs</artifactId>
    </dependency><dependency>
      <groupId>io.thorntail</groupId>
      <artifactId>swagger-webapp</artifactId>
    </dependency>
  </dependencies>
</project>

Adding REST Services

You can add some REST resources to test your project, such as this simple HelloWorldEndpoint taken from Thorntail examples:

package com.example.demomicroservice.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.Date;

@Path("/time")
@Api(value = "/time", description = "Get the time", tags = "time")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorldEndpoint {

    @GET
    @Path("/now")
    @ApiOperation(value = "Get the current time",
            notes = "Returns the time as a string",
            response = String.class
    )
    @Produces(MediaType.APPLICATION_JSON)
    public String get() {
        return String.format("{\"value\" : \"The time is %s\"}", new Date());
    }
}

As you can see from the above example, the most interesting annotation is @Api which marks a class as a Swagger resource and provides some description that will be included in the Web UI. The project should also include a class extending javax.ws.rs.core.Application to define the rest @ApplicationPath:

package com.example.demomicroservice.rest;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/")
public class RestApplication extends Application {

}

Finally, we will include a class implementing the ContainerResponseFilter interface, which works like a filter for the ContainerResponse extension point on the server side, in order to filter the response message after the invocation has executed:

package com.example.demomicroservice.rest;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;


@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
        responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        responseContext.getHeaders().add("Access-Control-Max-Age", "-1");
        responseContext.getHeaders().add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    }

}

Running the Thorntail application

Build you application the usual way:

$ mvn clean install

Then you can run it as:

java -jar target/demo-thorntail.jar

To GET the JAX-RS resource simply issue:

$ curl http://localhost:8080/time/now

Then, by pointing your browser at http://localhost:8080/swagger.json you should see the API documented similar to this.

{

    "swagger": "2.0",
    "info": { },
    "basePath": "/",
    "tags": [
        {
            "name": "time"
        }
    ],
    "paths": {
        "/time/now": {
            "get": {
                "tags": [
                    "time"
                ],
                "summary": "Get the current time",
                "description": "Returns the time as a string",
                "operationId": "get",
                "produces": [
                    "application/json"
                ],
                "parameters": [ ],
                "responses": {
                    "200": {
                        "description": "successful operation",
                        "schema": {
                            "type": "string"
                        }
                    }
                }
            }
        }
    }

}

Now reach the Swagger UI at: http://localhost:8080/swagger-ui and provide as input the swagger.json:

thorntail rest example tutorial

As you can see, you have access to REST Services as describer by the swagger.json. By clicking on them, you can test them as well from the Swagger UI!

Enjoy Thorntail and REST Services!