Popular searches
//

Swagger for Akka HTTP

31.3.2016 | 10 minutes reading time

In this post I’m hoping to give you a good insight in how to setup Swagger for Akka HTTP.

Swagger is a tool to document REST API’s and overall works quite nicely to test some basic API commands. It already has integrations with many languages / REST frameworks. Since recently, Akka HTTP has been fully incorporated in the Akka platform. Swagger support for Akka HTTP exists, but the setup has some oddities. Here, I hope to provide you with a complete guideline.

Swagger Background

Swagger consists of two main parts; the Swagger UI and a server-side library. The server-side library is responsible for generating the API documentation from the code and supplemental annotations. This generated file is parsed by the Swagger UI, which in turn will provide an HTML app to view and test your API.

The generated API documentation looks something like this (in JSON):


{
  "tags": [{
    "name": "users"
  }],
  "host": "0.0.0.0:8080",
  "paths": {
    "/users": {
      "get": {
        "description": "",
        "tags": ["users"],
        "operationId": "getAllUsers",
        "produces": ["application/json"],
        "parameters": [],
        "summary": "Get list of all users",
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": {
              "type": "array",
              "uniqueItems": true,
              "items": {
                "$ref": "#/definitions/User"
              }
            }
          }
        }
      }
    }
  },
  "basePath": "/",
  "info": {
    "description": "",
    "version": "1.0",
    "title": "",
    "termsOfService": ""
  },
  "schemes": ["http"],
  "definitions": {
    "Function1RequestContextFutureRouteResult": {
      "type": "object"
    },
    "User": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        }
      }
    }
  },
  "swagger": "2.0"
}

As server-side library for generating the API documentation, we will use the swagger-akka-http project.

Project Setup and Dependencies

A new project may be generated with sbt-fresh , giving us already a nice project setup containing most of what we need. The layout should look like this;


+ build.sbt             // specific settings for (single) module
+ project
--+ build.properties    // sbt version
--+ Build.scala         // common settings for all modules
--+ Dependencies.scala  // values for library dependencies
--+ plugins.sbt         // sbt-git, sbt-header, sbt-scalariform
+ README.md
+ src
--+ main
----+ resources
----+ scala
------+ package.scala   // type aliases repoining `Seq` and friends to immutable

For the swagger-akka-http library (and for Akka itself), we need to add the following dependencies to the build.sbt file. Be nice and add these dependencies as variables to the project/Dependencies.scala file 😉

We would like to include the Swagger UI in our app – especially in this demo – because it lets us easily serve the necessary pages. For this, download the entire latest Swagger UI repository as ZIP from GitHub . Extract the archive and copy all files under the dist folder to our project’s src/main/resources/swagger/ folder.

Now we’re all set for some real code.

Akka HTTP Setup

For our demo application, the API itself is not really that interesting. Let’s assume we want to retrieve the users in our system, and add new users. This at least gives us a HTTP GET and POST request to describe and play with.

First we need an entry point for our application; the main class so to say. It will start our Actor system and from there run the HTTP service as Actor. The full code is here for UserApp.scala:

As you can see in the code, it also initializes the UserRepository Actor. This Actor will function as a ‘stub’ for our persistent storage or other business logic. It doesn’t really matter for this demo application, just that we have some place where we can store and retrieve user records. Here is the code for UserRepository.scala:

And then finally the HTTP Service. I’m going to show you here a stripped-down version, to later show the full version with all annotations etc. necessary for Swagger.

What is most important, is that you split up the HTTP Service and especially our UserService into separate classes. This will let us annotate the UserService class separately, only exposing this one for Swagger. Should you have multiple services, then splitting them up in the right way will also make sure the operations are nicely grouped.

Swagger Setup

Now finally to the part where we configure Swagger to generate the API documentation.

Serve Swagger UI Resources

In one of the first steps, we added all resources for the Swagger UI. To serve them, we need to tell Akka HTTP where and how to serve these files. Luckily this is very easy and requires only two lines in our HttpService class (remember, I’ll show the full class at the end):

The first line tells Akka HTTP where it can find the necessary files, and that we want them served on the path /swagger. The second line adds this route definition to the total routes definition.

Swagger Annotations

First of all on the service level, we need to use the @Api annotation. This will tell Swagger this is an entry point for a REST service, and the path it maps to. For example:

The annotation for the GET request is also very easy. For this we use the @ApiOperation annotation. Most noteworthy here is the response and responseContainer attributes we have to supply. The response points to the class of the object that is being returned. It lets Swagger correctly show example responses (and later for the POST create example requests). The responseContainer is required when a list or set is returned, to describe the correct container type (and not to ‘pollute’ the object return type).

Lastly the annotation for the POST request. Again the @ApiOperation annotation is used, but now we also need the @ApiImplicitParams and @ApiResponses annotations. This last annotation is just to notify we may return other HTTP response codes besides 200 OK, and the reason why this response code might be returned.
The @ApiImplicitParams annotation describes the parameter supplied with the HTTP POST. Also here you need to point to a class so that Swagger can correctly describe the object. Strangely, where for the GET request @ApiOperation a class object was required, now the dataType attribute requires a string object.

For a full description of all Swagger annotations see https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X

Last thing to note, apparently the javax.ws.rs.Path is always necessary for Swagger to detect the service. So while it has no use for Akka HTTP, you need to include it for Swagger.

Swagger HTTP Service

The SwaggerHttpService is a trait that needs to be included to actually generate and provide the JSON API documentation described above. Most importantly, you need to point it to your REST services, in our case the UserService. The full class is described below:

And then we need to include it in the Akka HTTP route definition:

CORS Support

One last thing we need is to configure HTTP cross-origin access control. To make sure the Swagger UI works with our service when running on a different domain or on localhost. The CorsSupport class I included in my project is taken directly from https://github.com/pjfanning/swagger-akka-http-sample . It is this class: https://github.com/pjfanning/swagger-akka-http-sample/blob/master/src/main/scala/com/example/akka/CorsSupport.scala.
Now just to hook it up into our project:

Full HTTP Service Class

And finally the full HttpService class with the service, the annotations, CORS support etc.:

Disclaimer

The examples I showed you here are loosely based on Heiko Seeberger’s reactive-flows project regarding the Akka HTTP setup. A demo project can be easily generated with SBT-Fresh sbt-fresh .

Hope you liked this blog and would love to hear your comments!

//

More articles in this subject area

Discover exciting further topics and let the codecentric world inspire you.