Your REST APIs should always be documented. Your users need to know:
- The purpose of your API and each operation in it.
- What HTTP requests can be made, including which parameters can be sent in the URL path, URL query parameters, headers and the request body. Parameter constraints, e.g. validations, should also be documented.
- What HTTP responses they will receive, including the status code and headers the response may have, and what will be in the response body.
They should know this by reading your documentation before ever having to test your API. This will greatly improve their experience and understanding.
This guide suggests two ways to document a REST API: OpenAPI/Swagger and apiDoc. These are not the only ways, but they are popular tools.
The OpenAPI specification is a community-driven open specification within the OpenAPI initiative. It defines a standard, programming language-agnostic interface description for HTTP APIs, which allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or inspection of network traffic.
Swagger is a suite of open source tools which can be used with an OpenAPI document.
An OpenAPI document is a JSON or YAML document which follows the specification. Here's a short sample document which defines one API route (in the YAML format):
openapi: 3.1.0
info:
description: "This API is awesome."
version: "1.0.0"
title: "Awesome API"
paths:
/users/{id}:
get:
summary: Request a user's information.
parameters:
- name: id
in: path
description: The unique identifier of the user.
requestBody:
content:
application/json:
schema:
type: object
properties:
firstName:
type: string
description: First name of the user.
example: John
lastName:
type: string
description: Last name of the user.
example: Doe
Have a look at the Swagger Editor for a more complete example.
Using tools such as swagger-ui-express, an interactive HTML documentation can be generated from the OpenAPI document.
Put your OpenAPI document in a openapi.json
or openapi.yml
file in your
repository, depending on whether you prefer JSON or YAML.
Install the swagger-ui-express package in your Express application, as well as the js-yaml package if you prefer writing YAML rather than JSON:
$> cd /path/to/projects/my-project
$> npm install swagger-ui-express js-yaml
Add the following code in the imports section of your app.js
file:
import fs from 'fs';
import yaml from 'js-yaml';
import swaggerUi from 'swagger-ui-express';
And the following code somewhere under the const app = express();
line:
// Parse the OpenAPI document.
const openApiDocument = yaml.load(fs.readFileSync('./openapi.yml'));
// Serve the Swagger UI documentation.
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openApiDocument));
You should now be able to access your documentation through the Swagger UI at localhost:3000/api-docs
The OpenAPI schema defines what you can put in an OpenAPI document.
Be aware that when using swagger-ui-express, you are using the Swagger OpenAPI specification. You should use that as your reference.
With the code above, the Swagger UI is kept automatically up to date every time you launch your Express application.
If you use nodemon and have a
nodemon.json
configuration file, remember to add youropenapi.json
oropenapi.yml
file to thewatch
list innodemon.json
. This will make you application restart every time you modify the OpenAPI document.
- Use components to avoid repeating yourself if you have a chunk of your documentation that is the same for several routes.
- Document validation constraints by including JSON schemas in your OpenAPI document. A JSON schema is a standard way of validating a JSON document. Use the JSON Schema Reference and the JSON Schema Validation draft as your references.
- The swagger-jsdoc package allows you to put each route's documentation in a comment next to the route if that's your thing.
apiDoc creates a user-friendly documentation page from API annotations in your source code.
Put comments such as this in your code:
/**
* @api {get} /users/:id Request a user's information
* @apiName GetUser
* @apiGroup User
*
* @apiParam {Number} id Unique identifier of the user
*
* @apiSuccess {String} firstName First name of the user
* @apiSuccess {String} lastName Last name of the user
*/
The apidoc
command-line tool will parse these comments and use them to
generate a user-friendly HTML documentation.
Install apiDoc globally with:
$> npm install -g apidoc
Move into your project's directory and run apiDoc with two options:
- The
-i
option should be followed by the directory containing your documented API routes - The
-o
option should be followed by the directory where you want the generated documentation to be saved
$> cd /path/to/projects/my-project
$> apidoc -i routes -o docs
warn: Please create an apidoc.json configuration file.
info: Done.
Open the generated docs/index.html
file in your browser to see the result.
You can make your application serve this documentation by using the
express.static
middleware:
// Serve the apiDoc documentation.
app.use('/apidoc', express.static(path.join(__dirname, 'docs')));
It's good practice to create an apidoc.json
file in your project's directory
to configure some documentation properties:
{
"name": "My project",
"version": "1.0.0",
"description": "It is awesome",
"title": "My project",
"url" : "https://example.com"
}
This will get rid of the Please create an apidoc.json configuration file
warning when you run apiDoc.
You can also install and run apiDoc as a development dependency:
$> npm install --save-dev apidoc
Add an apidoc
script to your package.json
file:
{
"name": "my-project",
"scripts": {
"apidoc": "apidoc -i routes -o docs",
"...": "..."
},
"...": "..."
}
You and your teammates can now generate the documentation this way, without having to install the module globally on each machine:
$> npm run apidoc
Read the apiDoc documentation, namely the parameters you can use to document each route.
You will have to run the apidoc
command or your npm run apidoc
script every
time you modify an apiDoc comment.
-
It is customary to put an apiDoc comment next to the route it documents, but you can actually put it anywhere in your project.
-
Use
@apiGroup
to group routes together in the left-side menu. -
Use
@apiDefine
and@apiUse
to avoid repeating yourself if you have a chunk of documentation that is the same for several routes. -
Document validation constraints with the
@apiParam
parameter:/** * @apiParam (URL query parameters) {Number{1..}} [page] The page to retrieve * @apiParam (Request body) {String{3..50}} title The movie's title * @apiParam (Request body) {Number{0..10}} [rating] The movie's rating * @apiParam (Request body) {String="male","female"} gender The person's gender */
-
Specify a category in parenthese when using the
@apiParam
parameter in order to group request/response parameters together. For example:/** * @apiParam (URL path parameters) {String} id The movie's unique identifier * @apiParam (URL query parameters) {Number} page The page to retrieve * @apiParam (Request body) {String} title The movie's title * @apiParam (Request body) {Number} rating The movie's rating */