Merit | Blog

Generating APIs and Documentation with Swagger

Written by Erik Haliewicz | Dec 15, 2022

Streamlining API Documentation

Documentation is critical to API development, especially if multiple teams are building microservices and consuming each other's APIs. However, creating and keeping documentation synchronized requires extensive manual work. The only thing worse than no documentation is incorrect documentation.

Swagger at Merit

At Merit, we use Swagger to tackle this problem. Swagger is a language and set of tools designed to make developing and maintaining API documentation easier and less time-consuming. It also ensures our documentation and code remain consistent. 

By defining a specification (spec) for an API in either YAML or JSON, readable, interactive documentation and code are generated to implement and/or consume the API. 

Swagger tools:

  • generate code in many programming languages
  • generate html or text documentation
  • check the validity of a Swagger spec
  • and more

In this diagram, the team working on "Core service A" only needs to write a correct Swagger spec to support clients in numerous languages, create documentation for developers, and accommodate automated integration testing.

Defining a Swagger spec

Here is an example Swagger spec for one of the data structures in Merit's platform.

First, we define our data structure, a field kind. This is used as a generic field inside the Merit template data structure.

Here FieldKind is a composition of three other defined Swagger types:

BaseReadModel, OwnerMetadata, and FieldKindProps

BaseReadModel contains just an `id` field. OwnerMetadata describes who owns this object. FieldKindProps contains the following fields:

  • name
  • description
  • data type (string, date, email, etc.)
  • parent id (originally extended from)
  • validation rules
  • permissions

Next we can define an endpoint /v1/fields/{fieldID} which uses the FieldKind object:

This endpoint is specified to return a FieldKind corresponding to the passed-in field kind ID.

Generating Swagger API code

We generate a working API allowing an external program to access this endpoint. To generate the "go API" code, we use "go-Swagger." The generated API code is strongly typed, which ensures correct use with each data type. We execute the following command to generate data structures for the model definitions and API code.

Installing "go-Swagger," enables running the following command to generate data structures and API method definitions for the Swagger specification.

`swagger generate client --target=./gen/restapi --model-package=models`

This creates a new directory, `gen/restapi`, which contains the following: 

  • operations_client.go
  • get_field_kind_parameters.go
  • get_field_kind_responses.go

The following snippet shows an example of this code:

We obtain a directory `gen/models`, containing model definitions used by all endpoints. Any definitions not used by an endpoint are omitted from the generated code.

This code contains the following:

  • data structure definitions
  • validation
  • serialization code

The following block illustrates how this client code might be used:

Generating interactive documentation

To generate interactive documentation, we use the official Swagger codegen tool with the following command:

`swagger-cli bundle swagger.yaml --dereference --outfile ./gen/api.json`

This generates an api.json file which, when loaded into either the Swagger browser plugin or the official Swagger editor, generates an interactive web page containing both endpoint and model definitions, as shown below:

The Future of API Documentation at Merit

We are experimenting with another tool, Goa, that provides a clean "go DSL" for designing API specs. It is interoperable with Swagger and generates an equivalent Swagger specification (both Swagger v2 and v3). The benefit is the ability to write specifications in "go" directly while the compiler type-checks it, rather than manually writing YAML or JSON.

Pursuing automated testing with tools that generate testing code directly from a Swagger spec, we hope to add another valuable tool that will further shorten the process time and improve clarity and efficiency.