02 August 2020
Welcome to the seventh chapter of the API-only ruby on rails course. This time, we will implement the first part of the swagger documentation for the API endpoints. If you didn’t read the previous sections yet, you can check the content list from the overview page.
I assume most of you already know or used swagger for the API documentation and testing, but let me quickly explain why we want to use swagger. Swagger is a specification (recently called OpenAPI specification) that allows you to describe available API endpoints and operations on each endpoint using a JSON or YAML file. By using the swagger file with swagger UI, we can interactively document and test API endpoints. You can check the example swagger file here. You can also see how this file looks like using together with swagger UI here. As you can see, swagger UI allows client developers to see the living example of the API endpoints. They can see all the details of requests and responses for each endpoint.
For the swagger integration with rails applications, there are some different approaches. Some of them are using tests to document API. Using test files to generate API documentation feels like mixing two big responsibility into the one. Let’s say you have a strict deadline, which you might think about not maintaining the documentation for a while but want to have tests anyway. Using both of them in the same place will make it challenging to deal with that situation. You might think like “doing one of them is already covers both of them” but actually, you need to have more extended specs than the usual in case you want to generate swagger documentation from the specs.
The other approach is auto-generating the swagger documentation. Even though those libraries are announced as auto-generated, you still need to work on them. The nature of the ruby (a dynamically typed language) doesn’t allow you to understand the types of request parameters or response payload fields. Or if you have a
rescue block for all API endpoints for the
404 (not found) response, you need to document it anyway manually. So it’s half automation, half manual maintenance work.
Another approach is writing the documentation explicitly, which we will use along with the course. It will add maintenance costs to the development process, but it’s the easiest and pretty straightforward option.
I would like to use swagger-blocks gem to integrate swagger since it’s aligned with the third option that we discussed. The gem has a DSL that allows us to write API documentation manually. Also, we will create a controller which generates and exposes a JSON file from the code that we write by using
swagger-blocks DSL. (After we have a swagger JSON, we will integrate swagger-ui to show them interactively in the next chapters.)
Let’s start by adding
swagger-blocks gem to the
Gemfile and then run
bundle install command.
Now we will follow the instructions from the documentation of the
swagger-blocks gem. Let’s start by creating
Here, we defined the general information of the API documentation with specifying
basePath, etc. We will include other classes that describe the endpoints and resources to the
SWAGGERED_CLASSES, but we can ignore it for now. With the
index action, we’re building the JSON file using all classes specified. We don’t have any other class which uses
ApidocsController at the moment.
And now, we need to add
apidocs#index action to the routes.
If you go to the http://localhost:3000/apidocs address in your browser, it will render the swagger file generated, but we have only the general information of the API for now. Let’s add the necessary documentation classes for the user creation endpoint.
It’s better to have a namespace for the classes we would like to use with swagger. Therefore, let’s create a
swagger folder in the
app/controllers folder. Then, inside of the
swagger folder create
models folders. Controllers will reflect the classes that we use to document API endpoints, while models will reflect the request and response payloads.
Let’s start by creating
app/controllers/swagger/models/user_input.rb. It’s the file we define the request payload of the user creation endpoint.
Here, we basically defined the request payload fields for the
POST api/v1/users endpoint. After that we need to add this file to the
SWAGGERED_CLASSES inside the
And now we can document the user creation API endpoint. To do this, let’s create the
We added the request information for the
POST request of the user resource. We then defined the request details by specifying the
UserInput class that we described above as a request payload.
And again let’s add it to the
ApidocsController, as we similarly did with the
And if you go to the http://localhost:3000/apidocs you will see the generated JSON with the recent documentation we added with classes. For now, we don’t have any user interface to see what it looks like, but you can copy the generated file into the swagger editor and check how it works with swagger-ui. (To do that, you also need to adjust CORS settings, which we didn’t in the course yet!)
In this chapter, we started to build API documentation by using
swagger. We don’t have a user interface yet, but we have an action that generates the swagger file. In the next chapters, we will add responses to the API documentation along with the status codes and payloads. We will also integrate swagger UI into the project. You can find the source code of bookmarker application on github. You can also find the previous chapter here.
Thank you for reading! If you want to be notified when I publish a new chapter, you can follow me on twitter.