Yos Riady software craftsman 🌱

Automated REST API Development

Automated REST API Development

You’re building a REST API.

You develop an API backend with a few endpoints and deploy it to production. You publish several official language-specific API clients as well as an API documentation. Your API announces its public release; other developers start using it. Your day ends on a happy note.

The following day, you want to add a new feature to your API. You notice that you have to do a few things:

  • Update the server implementation to support the new feature.
  • Update the client libraries (one for each supported platform and language.)
  • Update the documentation.
  • All the above must be consistent with each other.

You let out a heavy sigh.

The Problem

For every update to your API, the above steps must be done each time to keep everything in sync with each other. Every officially supported API client must support the latest HTTP API endpoints. The documentation must also be consistent and true to the actual implementation.

Each of these steps are labour intensive and error prone. Thus, it makes sense for us to automate these tasks away so we can focus on actually building features.

API Specification Languages

API Specification Languages such as Swagger (aka OpenAPI) defines a language-agnostic, standard representation of your REST APIs. As the single Source of Truth of your API, we can directly autogenerate artifacts such as server stubs, client SDKs, and documentation from it that are consistent with your API specification.

Here is a minimal Swagger YAML spec:

swagger: '2.0'
info:
  version: 0.0.0
  title: Simple API
paths:
  /:
    get:
      responses:
        200:
          description: OK

You can open the above minimal.yaml spec on the online Swagger Editor.

As you can see, we have a specialized DSL to describe the endpoints of our API. In the above, we say that we have a GET endpoint at path / which returns a 200 OK response.

Take a look at some more examples on the online Swagger Editor to get a feel for the syntax. I will leave you to learn the Swagger syntax on your own time.

You might have observed that we’re taking a “Design First” approach by starting with defining a specification for our API before going to implementation. This approach takes an initial investment in spending time with Swagger, but will save you much time and effort in the long run.

Generating Clients

We can automatically generate server stubs and client SDKs using Swagger Codegen.

If you’d like, you can generate both stub and client from the online Swagger Editor directly without having to set up a local development environment:

Try Generate Server and Generate Client to download the generated code.

Installation is easy on Mac OSX:

brew install swagger-codegen

Point to a filepath containing your Swagger file and run swagger-codegen generate:

$ mkdir petstore-ruby-sdk
$ cd petstore-ruby-sdk
$ swagger-codegen generate -i https://petstore.swagger.io/v2/swagger.json -l ruby -o .
reading from https://petstore.swagger.io/v2/swagger.json
writing file /tmp/test/lib/swagger_client/models/order.rb
writing file /tmp/test/lib/swagger_client/models/user.rb
writing file /tmp/test/lib/swagger_client/models/category.rb
writing file /tmp/test/lib/swagger_client/models/tag.rb
writing file /tmp/test/lib/swagger_client/models/pet.rb
writing file /tmp/test/lib/swagger_client/models/api_response.rb
writing file /tmp/test/lib/swagger_client/api/user_api.rb
writing file /tmp/test/lib/swagger_client/api/store_api.rb
writing file /tmp/test/lib/swagger_client/api/pet_api.rb
writing file /tmp/test/swagger_client.gemspec
writing file /tmp/test/lib/swagger_client.rb
writing file /tmp/test/lib/swagger_client/api_client.rb
writing file /tmp/test/lib/swagger_client/api_error.rb
writing file /tmp/test/lib/swagger_client/configuration.rb
writing file /tmp/test/lib/swagger_client/version.rb

For your reference, the -i flag specifies the input file, -l specifies the target language, and -o specifies the output directory.

Get the list of available options with swagger-codegen help generate. To get the list of available options for a language, call swagger-codegen config-help -l ruby.

Below is the generated Ruby client:

|-- lib/
	  |-- swagger_client/
	           |-- api/
	           |-- models/
	           |-- api_client.rb
	           |-- api_error.rb
	           |-- configuration.rb
	           |-- version.rb
|-- swagger_client.gemspec

The full client code is available here.

You’re not limited to Ruby. You can generate client SDKs for about every major language or platform. Here is a list of built-in code generators:

async-scala
csharp
dart
flash
python-flask
java
javascript
jaxrs
inflector
jmeter
nodejs
objc
perl
php
python
qt5cpp
ruby
scala
scalatra
silex-PHP
sinatra
slim
spring-mvc
dynamic-html
html
swagger
swagger-yaml
swift
tizen
typescript-angular
typescript-node
akka-scala
CsharpDotNet2
clojure

Generating Server Stubs

You can also use swagger-codegen to generate a server. If you need to boostrap an API from scratch, you can use swagger-codegen to generate the the initial code.

$ mkdir petstore-node-server
$ cd petstore-node-server
$ swagger-codegen generate \
  -i https://petstore.swagger.io/v2/swagger.json \
  -l nodejs\
  -o .

We get:

|-- api/
|-- controllers/
	|-- Pet.js
	|-- PetService.js
	|-- Store.js
	|-- StoreService.js
	|-- User.js
	|-- UserService.js
|-- index.js
|-- package.json
|-- README.md

The full generated server code is available here.

Like the client generator, the server generator has many target languages / platforms available out of the box.

Generating Documentation

We can generate HTML documentation that is available as a single-page application with AJAX with swagger-codegen by passing in dynamic-html as the language option:

$ mkdir petstore-html-doc
$ cd petstore-html-doc
$ swagger-codegen generate -i https://petstore.swagger.io/v2/swagger.json -l dynamic-html -o .
$ npm install
$ node .

The above generates and launches a Node.js server for rendering the documentation.

Prefer static html? Use html instead of dynamic-html.

In addition, we can generate interactive documentation based on our API spec using swagger-ui. The nice thing about swagger-ui is you get an interactive API playground.

Here is a live demo.

Codegen HTTP API

Alternatively, you can skip local configuration and use the online generators. For example, to generate a Ruby API client, simply send the following HTTP request using curl:

curl -X POST -H "content-type:application/json" -d '{"swaggerUrl":"https://petstore.swagger.io/v2/swagger.json"}' https://generator.swagger.io/api/gen/clients/ruby

Then you will receieve a JSON response with the URL to download the zipped code.

Node Support

Swagger has especially good support for Node.js projects with:

If you’re using Node.js as your main stack, you want to check these projects out.

Alternatives

Recently, there have been efforts to standardize the plethora of API specification languages into a single, de-facto Open API Standard, which is based on Swagger 2.0.

However, you should know that there are other API specification ecosystems available out there, such as Heroku’s interagent which is based on JSON Schema.

In Closing

With a bit of initial investment, we’ve automated labour-intensive and error prone API development tasks away so we can focus on actually building features.

Author

Yos is a software craftsman based in Singapore.

📬 Subscribe to my newsletter

Get notified of my latest articles by providing your email below.


Going Serverless book

Interested to find out more about serverless? Going Serverless teaches you how to build scalable applications with the Serverless framework and AWS Lambda. You'll learn how to design, develop, test, deploy, and secure Serverless applications from planning to production.

Learn More →