API with Node.js, Express and Prisma

Introduction

What is an API?

API stands for Application Programming Interface. An API is a set of rules, protocols, functions, and tools that allow different applications to communicate with each other and share data or functionalities.

An API acts as a mediator between two applications that wish to exchange information (resources) or perform a set of actions through an interface.

More Information:

What is a Web API?

A Web API is a type of API specifically used for exchanging information between applications over the Web. In other words, a Web API allows different applications to communicate and share data over the internet using the HTTP and HTTPS protocols as an interface. In the context of the Web, this occurs between the client, such as a web browser or mobile app, and a server.

A Web API consists of a series of endpoints that represent the different resources the API exposes. Each endpoint has a unique URL and a set of parameters that can be used to send and receive information.

The parameters attached to the endpoint’s URL are known as query params, but data can also be sent in the body of the HTTP request using the body.

What is an HTTP request and response?

Every exchange of information between two entities on the Web using the HTTP protocol is carried out through requests (request) and responses (response). These have a standardized structure for sending and receiving information.

The request consists of attributes such as:

  • The HTTP verb
  • The path you want to access
  • The protocol version
  • The headers

The response is very similar and additionally includes:

  • The response code
  • The response text
  • Various headers
  • The response data or information

Understanding the components of these is quite useful, as they are largely used by Web APIs.

HTTP Verbs and Status Codes

The HTTP (Hypertext Transfer Protocol) defines a set of verbs and status codes that are used in the requests and responses between a client and a web server. Some of the most common HTTP verbs and status codes are:

HTTP Verbs:

  • GET: requests a representation of a resource.
  • POST: sends data to create a new resource on the server.
  • PUT: sends data to update an existing resource on the server.
  • DELETE: removes a resource on the server.
  • HEAD: requests a response similar to a GET request, but without the response body.
  • OPTIONS: returns the HTTP methods supported by a resource.
  • PATCH: sends data to partially update an existing resource on the server.

HTTP Status Codes:

  • 1xx (Informational responses): indicates that the request was received, and the server continues processing it.
  • 2xx (Successful responses): indicates that the request was received, understood, and successfully accepted.
  • 3xx (Redirections): indicates that additional action is required to complete the request.
  • 4xx (Client errors): indicates that the request contained incorrect data or could not be processed.
  • 5xx (Server errors): indicates that the server failed to process the request due to a server-side error.

Some common HTTP status codes are:

  • 200 OK: indicates that the request was successfully processed.
  • 201 Created: indicates that the server has created a new resource.
  • 400 Bad Request: indicates that the request couldn’t be understood due to invalid data.
  • 401 Unauthorized: indicates that the request lacks valid authentication.
  • 404 Not Found: indicates that the server couldn’t find the requested resource.
  • 500 Internal Server Error: indicates that the server encountered an internal error while processing the request.

More Information:

What is a REST Web API?

A REST Web API is a type of Web API that follows a set of architectural principles and constraints called REST (Representational State Transfer) to facilitate communication between different applications.

In a REST Web API, the resources that the API exposes are identified by a unique URL and can be accessed through standard HTTP methods, such as GET, POST, PUT, and DELETE. Each resource has a representation in a standard format, like JSON, and clients can request, send, and manipulate these resources through HTTP requests.

Additionally, a REST Web API operates on the principle of “stateless” operation, meaning each request made to the server must contain all the necessary information to process that request. No state or context is maintained on the server between requests, allowing the API to be easily scalable.

Best Practices for a REST Web API

There are several best practices that should be followed when designing a REST Web API to ensure good functionality, scalability, and security, such as:

  1. Use nouns instead of verbs to represent meaningful and consistent resources: Resource names in a REST API should be descriptive and meaningful, and consistent naming conventions should be followed throughout the API. Collections are named in plural.
  2. Use HTTP verbs consistently: HTTP verbs (GET, POST, PUT, DELETE, etc.) should be used consistently to perform CRUD (Create, Read, Update, and Delete) operations on the API’s resources.
  3. Use appropriate HTTP status codes: HTTP status codes should be used appropriately to indicate whether a request was successful, whether an error occurred, whether authentication is required, and other cases.
  4. Use JSON as the information exchange format.
  5. Implement pagination for large data sets: If a data set is too large to be returned in a single request, pagination should be implemented to split the results into smaller pages.
  6. Authentication and authorization: Use authentication and authorization to protect the API against unauthorized access and ensure that only authorized users can access the API’s resources.
  7. Documentation: Provide clear and comprehensive documentation for the API, including information on available resources, request parameters, and expected responses.

An example of a basic REST Web API contract for the task resource called todos would be:

VerbCodeOperationDescription
/api/todos/POST201CREATECreate a task
/api/todos/GET200READRead all tasks
/api/todos/:idGET200READRead a task
/api/todos/:idPUT / PATCH200UPDATEUpdate task information
/api/todos/:idDELETE200 (or 204)DELETEDelete a task

This contract is not set in stone, but the basic definitions should be respected. For instance, creating a task with the DELETE method instead of POST doesn’t make much sense. However, many more operations, nested resources, and more can be added. An API is said to be RESTful when it complies with this minimum contract.

More Information:

Response Format

While there isn’t a standard response format for RESTful Web APIs, an initiative called JSON API proposes a standardized response format that can be used to structure and format API response data.

The JSON API format defines a clear and consistent structure for response data that includes information about the requested resources, related links, metadata, and any errors that may occur. This makes it easier for developers to consume the API and work with the response data.

Key components of a JSON API response include:

  • data: the information of the requested resources in JSON format.
  • links: links related to the request, such as links to the next page of results in case of pagination.
  • meta: additional metadata associated with the request, such as pagination information or any other relevant details.
  • errors: information about any errors that occurred in the request, including an error code, an error message, and additional details about the error.

Furthermore, the JSON API also defines conventions for pagination, sorting, defining relationships, and filtering data.

Using the JSON API is optional, but it can be beneficial to ensure interoperability and consistency in how API responses are structured.

More Information:

Error Format

Specifically, regarding the error response format, a response standard exists called Problem Details for HTTP APIs, also known as RFC 7807. This standard describes a format for representing errors in an HTTP response.

The standard error response format has the following structure:

  • type: a URL link identifying the type of problem.
  • title: a brief description of the problem.
  • status: the HTTP status code indicating the type of error.
  • detail: a more detailed description of the problem.
  • instance: a URI specifically identifying the resource or instance that caused the problem.

Additionally, it’s possible to include other optional fields to provide additional information about the error, such as:

  • cause: a description of the root error that caused the issue.
  • suggestedAction: a suggestion on how the issue can be resolved.
  • invalidFields: a list of input fields that caused the problem.

Using RFC 7807 helps standardize how errors are handled in RESTful Web API responses, making it easier for application developers and end-users to understand and handle errors.

More Information:

Glossary of Terms

Below is a list of the terms previously mentioned which will be used from now on:

  • Resources: Refers to the representation of the information exposed by the API. As mentioned in best practices, names are used instead of verbs such as todos, users, groups, etc.

  • Entity: These are the data that represent the information about the resource, for example:

{
  "id": "1",
  "title": "Buy Milk"
}
  • Collection: Collections are a list of entities where each one has the same structure.

  • Route: This is the URL fragment used to identify the resources or actions exposed by an API, such as / (the root of the API), /api/todos, /api/groups/:id/todos, etc. Note that the routes are relative, meaning they are independent of the domain used to publish the API.

  • Endpoint: This refers to the combination of the HTTP verb and the route to access a resource or execute an action. In fact, the same route can be used with different verbs to express two different actions:

    • GET /api/todos
    • POST /api/todos
    • PATCH /api/todos/:id
  • Query params: As mentioned in best practices, you can send parameters attached to the URL to indicate the pagination of the entities returned by an endpoint. This is precisely using query params:

    • GET /api/todos/?limit=20&offset=10

In the previous example, two parameters are set for the endpoint that returns a collection of todos: limit with a value of 20 will limit the number of entities and offset with a value of 10 indicates the number of entities to omit in the endpoint result.

  • Body: To send data in the request body, the body is used along with the header so that the file type is interpreted as JSON.