Integrating Swagger with SUSI Server

The goal of Swagger is to define a standard interface for REST APIs which allows humans to understand the capabilities of the APIs without access to source code or documentation.

SUSI Server is now completely API centric. As more and more people make their own bots using SUSI Server they will be needing documentation for the APIs. We can use swagger so that without looking at the javadocs or documentation people can consume the REST APIs.

In this I post will walk you through the steps to integrate Swagger with SUSI Server which is running on Jetty.

Add the following dependencies to build.gradle file. These add Swagger Annotations, Swagger Models, Swagger UI and Glassfish containers.

  compile group: 'io.swagger', name: 'swagger-annotations',version: swaggerVersion
  compile group: 'io.swagger', name: 'swagger-core', version: swaggerVersion
  compile group: 'io.swagger', name: 'swagger-jersey2-jaxrs', version: swaggerVersion
  compile group: 'io.swagger', name: 'swagger-models', version: swaggerVersion
  compile group: 'org.glassfish.jersey.core', name: 'jersey-server', version: versionJersey
  compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet-core', version: versionJersey
  compile group: 'org.webjars', name: 'swagger-ui', version: '2.1.4'

Now SusiServer.class is the main file which initializes all the servlets and server handlers.

Here, we need to tell the SusiServer to look for the swagger annotations and use them to build the documentation.

In the main function, before starting the server we set the serverHandlers from setServerHandler function.

public static void main(String[] args) throws Exception {
  // init the http server
        try {
            setupHttpServer(httpPort, httpsPort);
        } catch (Exception e) {
            Log.getLog().warn(e.getMessage());
            System.exit(-1);
        }
        setServerHandler(dataFile);
        
        SusiServer.server.start();
        SusiServer.caretaker = new Caretaker();
        SusiServer.caretaker.start();

Now, we will modify the setServetHandler function for registering the Swagger Handler.

There are already 2 handlers so I used a handerCollection object, so that we can give multiple handlers to handerCollection and set the serverHandler as handerCollection.

private static void setServerHandler(File dataFile){
         ServletContextHandler servletHandler = new ServletContextHandler();
       handlerCollection.addHandler(ipaccess);
        ContextHandlerCollection contexts = new ContextHandlerCollection();
        ServletContainer sc = new ServletContainer(resourceConfig);
        ServletHolder holder = new ServletHolder(sc);

        servletHandler.addServlet(holder, "/docs/*");
        handlerCollection.addHandler(contexts);

        SusiServer.server.setHandler(handlerCollection);
}

servletHandler.addServlet(holder, “/docs/*”), this line in the setServerHandler method sets the default swagger.json path to api.susi.ai/docs/swagger.json

This is all the basic setup to initialize swagger and now we need to modify our API endpoints and set annotations for the base URL and parameters.

Now I will discuss how to add swagger annotations to our Servlets.

For the demo, I will use GetAllUsers.class file, which returns the list of all users to Admins.

@Path("/aaa")
@Api(value = "/AAA")
@Produces({"application/json"})
public class GetAllUsers extends AbstractAPIHandler implements APIHandler {

Just before the class starts we will add the Path of the API endpoint and the result it produces. In this case, GetAllUsers returns JSON and is a part of aaa group.

@GET
@Path("/getAllUsers.json")
@ApiOperation(value = "Get All Users Registered on SUSI.AI",
        notes = "This API Endpoint returns the list of all users registered on SUSI Server",
        responseContainer = "Object")
@ApiResponses(value = { @ApiResponse(code = 200, message = "Success"),
@ApiResponse(code = 401, message = "Base user role not sufficient") })

Inside the class, we will declare the path of the API endpoint. A description of this endpoint and the sample response code.

In this file, there are only two possible responses.
1. Response code 200 – when everything goes well.

2. Response code 401 – when base user role is not sufficient, i.e when user is not Admin

When we save the file and browse to 127.0.0.1/docs/swagger.json
We get a response something like –

The Swagger UI is used to parse this JSON and create a UI for the documentation, where we can see the sample responses of the API endpoints, error codes and other things.

Swagger UI presents us the API documentation something like this image below.

Resources

Susi Server:  http://github.com/fossasia/susi_server/

Swagger: https://swagger.io/

Swagger and Jetty Tutorial: http://robferguson.org/2016/12/11/resteasy-embedded-jetty-fat-jars-swagger-and-swagger-ui/