Building RESTFull APIs is a typical use case for Node.js. There are two typical approaches:
- API First - define the API, use tools to help scaffold and then fill in the implementation.
- Code First - implement the APIs and then generate documentation based on exposed API
The team's experience is that the API first approach based on OpenAPI provides benefits in both initial implementation and maintenance and our recommended packages and guidance is based on that approach, particularly if one or more of the following are true:
- New project without existing API
- Client side and backend are developed by different teams that need way to communicate API changes
- Development on clients and backends starts around the same time giving developers ability to mock API based on OpenAPI spec
NOTE: This section of the reference architecture focuses on building RESTfull APIs. For GraphQL please refer to the GraphQL Guide section.
With the API-first approach, designing the API is the first priority before writing any code. Design of the API involves thorough thinking and planning through collaboration with different teams (both client and backend side). This results in high-level documentation describing the intent of the API and ability to build client without waiting for server to be finished.
This API contract acts as a central draft keeping all your team members aligned on what your API’s objectives are and how your API’s resources are exposed. The finalization of the contract allows the team to build the interface of the application.
After this, the cross-functional teams rely on this interface to build the rest of the application independent of each other. In practice, teams can generate backends stubs and fully functional client libraries to avoid deviation from specification set in the OpenAPI spec file.
Code first approach provides libraries that understand server side backend structure and generate respective OpenAPI files. In this approach full control over API lies within server side team - generated OpenAPI file is read only and cannot be effectively used to negotiate API between client and server.
API first approach uses OpenAPI file as source of truth. Both client and server side generate code based on the OpenAPI file.
List bellow provides comprehensive set of libraries that can be used for an end to end full stack application written in Node.js, Express.js as well as client side applications.
The nodejs-express-server option can be used to generate Express.js based stub implementations based on your OpenAPI file.
npx openapi-generator-cli generate -g nodejs-express-server -i yourapi.json -o ./yourproject
The typescript-node option can be used to generate a client for Node.js applications that allows us to perform requests against another backend
openapi-generator generate -g typescript-node -i yourapi.json -o ./yourproject
openapi-backend allows you to mock based on an OpenAPI definition by returning predefined strings. The library provides way not only return predefined stubs but also perform validation or handle different use cases depending on request
@stoplightio/prism allows you to automatically mock API using OpenAPI spec definitions. This package is recommended if you need is an out of the box way to mock API without any development involved.
express-openapi-validator is a validator for express middleware that some of the build have used successfully.
vscode-openapi is a VScode plugin for building and validation of OpenAPI files that members of the team using vscode have used successfully.
Based on the teams experience we recommend the following:
- Define the API using OpenAPI 3.0, you can write the OpenAPI definitions in YAML or JSON formats, the team does not have a preference for one over the other.
- Prefer generating code from OpenAPI file for both client and server. Generating code based on the specification will ensure that the same types, formats are used. This will enable your team to iterate on the specification without worry of getting out of sync.
- When making changes in the OpenAPI file change it's version. Changed version will help others to detect what kind of changes were made.
- When introducing breaking changes consider adding them as new endpoints by introducing another v2 prefix in the API path.
- Every path should have
operationIdfield specified. This field is used by generator to generate method names for clients etc.
- When building response objects prefer referencing predefined Objects and Enums in Schemas
- If an API returns a specific error object it should be defined in the Schemas.
- Declare servers and security scheme to enable users to call API from OpenAPI Editor and other tools.
- Use tags to define namespaces for your API. Grouping operations with tags that will be used to organize your generated source code into folder structure.
OpenAPI spec provides an complete and minimalistic PetStore example. This example follows all the best practices and patterns for building API.