Announcing servant-swagger and swagger2

Servant is not the first project to provide a unified way of documenting APIs. There is API Blueprint, RAML, Apiary, and finally swagger. While these Web API description languages are not also web frameworks , they are generally very mature, and have some amazing tooling. For example, take a look at what swagger-ui, a client-side HTML, CSS, and JS bundle, does with your swagger API description here.

As you can see, it’s a very convenient and approachable way of exploring your API. In addition to an easily-navigable structure, you can build up requests and send them to your server, and see its responses.

But it doesn’t end there. If you have a swagger specification of your API, you can also take advantage of the large variety of languages for which you can generate a client library automatically. You don’t even need to build the Java code - you can just use the “Generate Client” button in the beautiful swagger editor.

There are a wide array of other tools that support swagger. Obviously, having access to them would be a great boon. The problem so far has been that writing and maintaining a swagger specification, that you can be sure matches your service, is hard work.

swagger2 and servant-swagger

Thankfully David Johnson and Nickolay Kudasov have written two Haskell libraries, swagger2 and servant-swagger, that automate nearly all of that process for servant APIs. They use the mechanism that guides most of the servant ecosystem — interpreters for the type-level DSL for APIs that is servant — to generate a swagger spec for that API.

Let’s see how it is used; as an example, we’re going to take the Gists part of the GitHub API v3. For the purpose of this post we will ignore authentication and consider only GET requests which do not require one. Furthermore, we’ll use simplified representation for the responses (i.e. we are also ignoring some fields of the response objects).

First the imports and pragmas (this is a literate haskell file):

The API:

Data types:

FromJSON instances:

So far this is what you would usually have when working with servant. Now to generate Swagger specification we need to define schemas for our types. This is done with ToParamSchema and ToSchema instances:

These will give us a generically-derived Swagger schema (which is sort of a deterministic version of JSON Schema).

Part of the swagger2 package, Schema and ParamSchema can be quite useful in their own right if you want to e.g. respond with a schema in case of bad request bodies, or OPTIONS requests.

The next step will traverse the GitHubGistAPI, gathering information about it and swagger2 schemas to generate a Swagger value:

Now we can generate the swagger documentation:

You can attach more information to your Swagger doc quite easily, using the lenses provided by swagger2:

Which results in this.

There’s a lot more you can do with both servant-swagger and swagger2 — write manual ToSchema instances for more detailed information, conveniently add tags or change responses of parts of your API, use convenient lenses to modify any part of your schema, generate automatic tests, etc.

Check out the servant-swagger and swagger2 docs for more.

These two new packages vastly expand the landscape of tools within easy reach of application developers using servant. Time to explore that landscape!

On a related note, Masahiro Yamauchi has recently added Servant codegen for Swagger. So not only can you generate a swagger description for your servant server, but you can also generate the servant description from a swagger one too!