Bump.sh

Creating an API with Express.js using OpenAPI

Express is a popular backend JavaScript framework for building landing pages and integrated content management systems or integrating APIs with other tools. With over twenty million weekly downloads on npm at the time of writing, the framework’s popularity comes from its ease of setup and use, extensibility with first- and third-party middleware functions, and its flexible built-in router.

OpenAPI is a standard for describing HTTP APIs in a document that humans and computers alike can understand or consume. Building APIs according to the OpenAPI specification can ease friction between an API’s developer and its consumers, especially in terms of how the API should operate. Some knowledge about the OpenAPI specification can definitely help you understand the examples provided.

In this article, you’ll learn how to build REST APIs using Express. You’ll also learn how to document your APIs according to the OpenAPI specification with express-openapi. Finally, you’ll learn how to effectively manage your API documentation using Bump.sh.

Crash Course in Express #

The Express architecture is based around middleware, which are functions that can access and modify the request and response object and either return a response or trigger subsequent middleware functions. Middleware can be registered by invoking the .use() method on an Express application, like so:

import express from 'express';
import middlewareFunction from 'my-middleware-function';

const app = new express();

app.use(middlewareFunction);

Express has three built-in middleware functions for serving static files (express.static, parsing JSON (express.json) and URL-encoded request payloads (express.urlencoded). Together with the Express router, these provide a good starting point for most applications.

The Case for OpenAPI #

The OpenAPI specification is an opinionated, language-agnostic standard for describing HTTP APIs that allows humans and machines to understand and interact with an API without the need to access the source code. A valid OpenAPI description document is also called an API contract because, like a contract, it enforces a specific behavior that must be implemented by the developer and adhered to by the consumer.

An API contract adds value in many ways, including easing the development burden, improving ease of adoption for first-time consumers, and using automated tools to reduce the amount of work needed to generate client code and documentation or validate I/O data.

In the next few sections, we’ll see API contracts in action as we build an Express application and generate documentation with Bump.sh.

Implementing an API with OpenAPI and Express #

In this section, using Express, you’ll build an API that follows the OpenAPI specification. You will be walked through steps to set up an Express application, configure it according to the OpenAPI spec, and see how to view your API documentation.

Prerequisites #

In order to follow along with this tutorial, you’ll need the following:

  • Familiarity with JavaScript (and Node.js)
  • Node.js
  • A Node.js package manager — npm was used in this article
  • A Bump.sh account

You can find the source code for the project in this GitHub repo.

Creating an Express Application #

Let’s start with creating an Express application. As mentioned, one of the reasons Express is so popular is that it’s quick and easy to set up.

First, create a new folder for your project. Spin up a terminal session and run the following command to create a folder named express-oas:

mkdir express-oas

Next, initialize a JavaScript project by adding a package.json file. Using the same terminal session or via your computer’s file manager, create a file named package.json:

cd express-oas
touch package.json

Open the package.json file using a text editor, then copy and paste the following in the file:

{
  "name": "express-oas",
  "main": "index.js",
  "scripts": {},
  "dependencies": {
    "express": "^4.18.2"
  }
}

You can also use npm init or yarn init to automatically generate a package.json file. Both npm init and yarn init (on Yarn Classic) run interactively, meaning that you’ll need to respond to a series of prompts before the file is generated. To skip these prompts and use the defaults, you can run the command with the -y flag:

# Run interactively
npm init

# Run non-interactively
npm init -y

Finally, install the express package dependency from the npm or yarn registry and create your Express application.

In your terminal, run the command to install dependencies:

npm install

Next, create a file named index.js in your project’s root folder. You can do that via the terminal by running the following:

touch index.js

Open this file using your text editor, then import and initialize your Express application:

import express from 'express';

const PORT = 3000;

const app = new express();

app.use(express.json());

app.listen(PORT, () => {
	console.log(`Server running on ${PORT}`);
});

The default export from the express package is a function that, when invoked, creates an express application instance. This instance or object contains methods for routing HTTP requests, configuring middleware, and binding and listening for connections on a specified host and port.

In the code block above, you configured an Express application and registered the json() middleware, which parses incoming requests with JSON payloads and a matching Content-Type header.

If you try to access the application at this stage by running node index.js and navigating to http://localhost:3000 on a web browser, you’ll be greeted by an error. There’s no need to worry about this, however, as it just indicates that there are no routes or logic configured in your application yet. In the next section, we’ll add some logic and set up the application’s documentation with express-openapi, an OpenAPI framework for Express.

Integrating OpenAPI with express-openapi #

For developing APIs, it helps to think of the API as a collection of resources, with each resource represented by a simple object that can be—from the moment of its creation—viewed, modified, or destroyed.

For simplicity, you can use this create, read, update, and delete (CRUD) pattern to help plan or design your API quickly. You can set up an OpenAPI-compliant API in a few steps using the express-openapi package. For this one we will assume that our project has only one resource, called User.

express-openapi is an un-opinionated OpenAPI framework for Express, which supports OpenAPI versions 2.x and 3.0 at the time of writing. Configuration can be done in JavaScript or from a YAML string/file. In this project, you’ll be using a JavaScript object.

express-openapi allows you to keep the OpenAPI documents in sync with the code. Basically, you will provide an OpenAPI document with empty paths and they will be populated from your code. Doing this ensures the OpenAPI document will be exactly reflecting how the code behaves, updated as the code is. It also allows you if you go play around with the tool to validate your schemas, automatically provide res.validateResponse tailored to a particular route, helps with your API security management, and so much more I can’t list them all now. The whole purpose of this framework is to stay as close as possible to express while leveraging the power of OpenAPI.

To get started, run this command in your terminal to install the package:

npm install express-openapi

Open the index.js file in your editor and add the following import near the top of the file: