This is an exhaustive tutorial to create a simple backend application that is compliant with OpenAPI specifications.

Create a Simple Express.js App

You can download the simple Express.js app template from this repository and jump directly to the next section, “Add TSOA”.

Start with a blank project. Create a folder src in your project’s root, and there create a file named main.ts in it. Fill main.ts with the following code, which is the standard Hello World code for Express.js:

Install express with node package manager, compile the code, and run it:

$ npm install express

$ npm install typescript

$ tsc src/main.ts

$ node src/main.js

Structurize the Project

As you can see, the compiled version ( .js file) is generated in the same folder as your TypeScript file exists. We want to separate the source files from the compiled JS. Also, we want to keep a better track of our third-party packages.

For the latter, we should create a package.json file and put on the root folder of the project. Running the following command will do it for us, one just needs to answer the questions accordingly:

$ npm init

After initializing the package, all the already installed packages will be listed as [production] dependencies. The following command will move typescript into the development dependencies:

$ npm install typescript --save-dev

In my case, the resulting package.json file looks like this:

Now, create a TypeScript config file, namely tsconfig.json , under src and fill it with the following content:

Using the following command will compile all the TypeScript files under src and put them under dist folder.

$ tsc -p src

Now, to run the server do:

$ node dist/main.js

After adding custom package.json scripts, TSLint rules, and .gitignore , the project would look like this.

Add TSOA

TSOA (TypeScript OpenAPI) is an open-source tool for generating OpenAPI-compatible REST endpoints and generate Swagger config file, as well as routers for a middleware such as Express.js.

Start by adding the package to our project:

$ npm install tsoa --save-dev

$ npm install @types/node --save-dev

Create Controllers and Generate Routes

Create src/controllers/index.controller.ts and fill it with the following code:

Add "experimentalDecorators": true option to src/tsconfig.json file to enable decorators for TypeScript:

Add the config file tsoa.json to the project root:

Generate the routes and put them in src/routes :

$ mkdir -p src/routes

$ tsoa routes

Import RegisterRoutes from the generated routes files and call it by passing the Express.js app to it:

Now one can start the server and access the endpoints:

$ npm run server

The URL for the endpoints are /api/v1/ and /api/v1/msg/ :

$ curl localhost:3000/api/v1/

$ curl localhost:3000/api/v1/msg/

Generate Swagger Config

Create the folder api/dist and generate the Swagger config using TSOA:

$ mkdir -p api && mkdir -p api/dist

$ tsoa swagger

Now it is possible to start the Swagger UI using Docker:

$ docker run -p 8080:8080 -v ${PWD}/api/dist:/swagger -e SWAGGER_JSON=/swagger/swagger.json swaggerapi/swagger-ui

Open localhost:8080 on a browser to see the Swagger UI. The endpoints are listed correctly (at least, this is the expected behavior), but if you try them out, the Swagger UI would say:

TypeError: Failed to fetch

Opening browser’s console, one would learn that the original error is:

It’s because Swagger UI is trying to use HTTPS, which is not currently available.

Support HTTPS

To use HTTPS one must have SSL certificates. Please either create them locally or download them from a website like Let’s Encrypt. Assuming that you have the certificate ready, put the crt file as well as the private key in a subfolder, say cert . Then your main.ts would become the following:

Add TSOA Build Scripts

To generate routers and Swagger config easier, one shall create custom scripts in package.json . Add the following scripts to your package.json file:

Now one can build routes, Swagger config, and compile sequentially with the following command:

$ npm run build:all

Add Docker

For easier deployment, it is recommended to use Docker-Compose. But, to do so, we first need to build an image for our web application.

Add Dockerfile for Express.js App

Add the following content as Dockerfile to the project root:

Build the image using and run it using the following commands:

$ docker build -t aerabi/exptress-ts .

$ docker run -p 3000:3000 aerabi/express-ts

Add Docker-Compose Config

Now we can use the web application Docker image to create a Docker-Compose config, namely docker-compose.yaml , on the root:

Now, one can run the whole package using:

$ docker-compose up

Conclusion

The step-by-step tutorial of using Express.js with TypeScript, TSOA, and Swagger UI was presented. A version of the resulting project can be found on this Github repository.