Why I chose 'routing-controllers' over 'tsoa' for building routing and documenting APIs.
Table of Contents
Summary #
Creating type-safe routing and documenting is vital when building a Restful API server. In Express.js with TypeScript, some popular options for defining the routes are routing-controllers, tsoa and Nest.js.
But I will exclude Nest.js in this article because we need to apply it to an application already configured with native express.js.
So this article will explain the difference between the other two options and why I chose routing-controllers
over tsoa
.
Details #
Comparison #
routing-controllers | tsoa | |
---|---|---|
Type-Safe Routing | Decorator-based | Code-generation and using decorators |
Flexibility | Decorator-based, with a variety of decorators for fine-grained control | Code-generation, with limited customization options |
Documentation | Automatically generates OpenAPI (Swagger) schema object. | Automatically generates OpenAPI (Swagger) JSON file. Supports customizing the generated documentation. |
Type-Safe Routing
routing-controllers
It is decorator-based, meaning you can use decorators to define your routes and controllers. It also provides a simpler and more intuitive approach to routing by allowing you to define your routes and controllers in a way that is easy to read and understand.tsoa
It is code-generation and uses decorators. It takes your TypeScript code, looks for decorators, generates the necessary express routes, and the OpenAPI specification for your API. It aims to provide a more automated and less error-prone approach to API development by using TypeScript decorators to describe your API.both of them are type-safe.
using class-validator, you can validate the request body, params, query, and headers.
Flexibility
routing-controllers
It is decorator-based, with a variety of decorators for fine-grained control. It provides a lot of decorators for customization. It also supports a wide range of middleware and libraries.tsoa
It is code-generation with limited customization options. It generates boilerplate code, saving time and effort. But it can be less flexible and require additional setups such as a tsoa config file for building a routing file & an open API JSON file.routing-controllers
is more flexible thantsoa
.
It can use its existing middleware. Also, unliketsoa
, you can use express.req and express.res inside the controller.
Documentation
routing-controllers
It automatically generates OpenAPI (Swagger) schema object.
Generates OpenAPI (Swagger) specs automatically without any handling option. But it needs to use third-party libraries, such as routing-controllers-openapi and class-validator-jsonschema.tsoa
It automatically generates OpenAPI (Swagger) JSON file.
Supports customizing the generated documentation. It generates OpenAPI (Swagger) specs automatically. But it can be less flexible and require additional setups such as a tsoa config file for building a routing file & an open API JSON file below.example tsoa config file and script in package.json
- package.json- tsoa.json, tsoa.production.json1 2 3 4 5 6 7 8
{ ... "scripts": { "build": "tsoa spec-and-routes -c=tsoa.production.json && tsc -p ./", "dev": "cross-env NODE_ENV=development concurrently \"nodemon -x tsoa spec-and-routes -c=tsoa.json\" \"nodemon\"", } ... }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
{ "entryFile": "src/server.ts", "noImplicitAdditionalProperties": "throw-on-extras", "controllerPathGlobs": ["src/**/*.controller.ts"], "spec": { "host": "localhost:3000", "basePath": "/api", "schemes": ["http"], "outputDirectory": "src", "specVersion": 3 }, "routes": { "routesDir": "src", "basePath": "/api" }, "compilerOptions": { "baseUrl": "src", "paths": { "@/*": ["*"] }, "ignoreFiles": ["src/**/*.test.ts", "src/**/*.test.tsx", "src/**/*.test.js", "src/**/*.test.jsx"] } }
tsoa
is more convenient, butrouting-controllers
is more flexible.
Conclusion #
I tried both methods to add type-safe routing and documentation to an already implemented express server, and My choice was routing-controllers.
tsoa
had a lot of modifications to make to use the library, so it was inconvenient. to generate the spec and route codes, i also needed to modify the server execution script in package.json.
routing-controller
was a much better option to me, allowing us to use the already implemented middleware and controller logic and write more detailed swagger documentation.