Book Image

RESTful Web API Design with Node.js 10 - Third Edition

By : Valentin Bojinov
Book Image

RESTful Web API Design with Node.js 10 - Third Edition

By: Valentin Bojinov

Overview of this book

When building RESTful services, it is really important to choose the right framework. Node.js, with its asynchronous, event-driven architecture, is exactly the right choice for building RESTful APIs. This third edition of RESTful Web API Design with Node.js 10 will teach you to create scalable and rich RESTful applications based on the Node.js platform. You will be introduced to the latest NPM package handler and understand how to use it to customize your RESTful development process. You will begin by understanding the key principle that makes an HTTP application a RESTful-enabled application. After writing a simple HTTP request handler, you will create and test Node.js modules using automated tests and mock objects; explore using the NoSQL database, MongoDB, to store data; and get to grips with using self-descriptive URLs. You’ll learn to set accurate HTTP status codes along with understanding how to keep your applications backward-compatible. Also, while implementing a full-fledged RESTful service, you will use Swagger to document the API and implement automation tests for a REST-enabled endpoint with Mocha. Lastly, you will explore some authentication techniques to secure your application.
Table of Contents (16 chapters)
Title Page
Copyright and Credits
Packt Upsell
Contributors
Preface
Index

REST fundamentals


It actually happened back in 1999, when a request for comments was submitted to the Internet Engineering Task Force (IETF; http://www.ietf.org/) via RFC 2616: Hypertext Transfer Protocol-HTTP/1.1. One of its authors, Roy Fielding, later defined a set of principles built around the HTTP and URI standards. This gave birth to REST as we know it today.

Note

These definitions were given in https://www.ics.uci.edu/~fielding/pubs/dissertation/fielding_dissertation.pdf in the fifth chapter, Representational State Transfer (REST), of Fielding's dissertation called Architectural Styles and the Design of Network-Based Software Architectures. The dissertation is still available at http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm.

Let's look at the key principles around the HTTP and URI standards, sticking to which will make your HTTP application a RESTful service-enabled application:

  1. Everything is a resource
  2. Each resource is identifiable by a unique identifier (URI)
  3. Resources are manipulated via standard HTTP methods
  4. Resources can have multiple representations
  5. Communicate with resources in a stateless manner

Principle 1 – Everything is a resource

To understand this principle, one must conceive of the idea of representing data by a specific format and not by a physical file containing a bunch of bytes. Each piece of data available on the internet has a format that describes it, known as the content type; for example, JPEG images, MPEG videos, HTML, XML, text documents, and binary data are all resources with the following content types: image/jpeg, video/mpeg, text/html, text/xml, and application/octet-stream.

Principle 2 – Each resource is identifiable by a unique identifier

Since the internet contains so many different resources, they all should be accessible via URIs and should be identified uniquely. Furthermore, the URIs can be in a human-readable format, despite the fact that their consumers are more likely to be software programs rather than ordinary humans.

Human-readable URIs keep data self-descriptive and ease further development against it. This helps you to keep the risk of logical errors in your programs to a minimum.

Here are a few sample examples of such URIs representing different resources in a catalog application:

These human-readable URIs expose different types of resources in a straightforward manner. In the preceding example URIs, it is quite clear the data is items in a catalog, which are categorized watches. The first link shows all the items in the category. The second shows only the ones that are part of the 2018 collection. Next is a link pointing to the image of the item, followed by a link to a sample video. The last link points to a resource containing items from the previous collection in a ZIP archive. The media types served per each URI are rather easy to identify, with the assumption that the data format of an item is either JSON or XML, so we can easily map the media type of a self-described URL to one of the following:

  • JSON or XML documents describing the items
  • Images
  • Videos
  • Binary archive documents

Principle 3 – Manipulate resources via standard HTTP methods

The native HTTP protocol (RFC 2616) defines eight actions, also known as HTTP verbs:

  • GET
  • POST
  • PUT
  • DELETE
  • HEAD
  • OPTIONS
  • TRACE
  • CONNECT

The first four of them just feel natural in the context of resources, especially when defining actions for data manipulation. Let's make a parallel with relative SQL databases where the native language for data manipulation isCRUD(short forCreate, Read, Update, and Delete), originating from the different types of SQL statements, INSERT,SELECT,UPDATE, andDELETE, respectively. In the same manner, if you apply the REST principles correctly, the HTTP verbs should be used as shown here:

HTTP verb

Action

HTTP response status code

GET

Retrieves an existing resource.

200 OK if the resource exists, 404 Not Found if it does not exist, and 500 Internal Server Error for other errors.

PUT

Updates a resource. If the resource does not exist, the server can either decide to create it with the provided identifer or return the appropriate status code.

200 OK if successfully updated, 201 Created if a new resource is created, 404 Not found if the resource to be updated does not exist, and 500 Internal Server Error for other unexpected errors.

POST

Creates a resource with an identifier generated at server side or updates a resource with an existing identifier provided from the client. If this verb is to be used only for creating but not for updating, return the appropriate status code.

201 CREATED if a new resource is created, 200 OK if the resource has been updated successfully, 409 Conflict if the resource already exists and update is not allowed, 404 Not Found if the resource to be updated does not exist, and 500 Internal Server Error for other errors.

DELETE

Deletes a resource.

200 OK or 204 No Content if the resource has been deleted successfully, 404 Not Found if the resource to be deleted does not exist, and 500 Internal Server Error for other errors.

 

Note that a resource might be created by either the POST or PUT HTTP verbs, based on the policy of an application. However, if a resource has to be created under a specific URI with an identifier provided by the client, then PUT is the appropriate action:

PUT /categories/watches/model-abc HTTP/1.1
Content-Type: text/xml
Host: www.mycatalog.com

<?xml version="1.0" encoding="utf-8"?>
<Item category="watch">
    <Brand>...</Brand>
    </Price></Price>
</Item>

HTTP/1.1 201 Created 
Content-Type: text/xml 
Location: http://www.mycatalog.com/categories/watches/model-abc

However, in your application, you may want to leave it up to the backend RESTful service to decide where to expose the newly created resource, and thus create it under an appropriate but still unknown or non-existent location.

For instance, in our example, we might want the server to define the identifier of newly created items. In such cases, just use the POST verb to a URL without providing an identifier parameter. Then it is up to the service itself to provide a new unique and valid identifier for the new resource and to expose back this URL via the Location header of the response:

POST /categories/watches HTTP/1.1
Content-Type: text/xml
Host: www.mycatalog.com

<?xml version="1.0" encoding="utf-8"?>
<Item category="watch">
    <Brand>...</Brand>
    </Price></Price>
</Item>

HTTP/1.1 201 Created 
Content-Type: text/xml 
Location: http://www.mycatalog.com/categories/watches/model-abc

Principle 4 – Resources can have multiple representations

A key feature of a resource is that it may be represented in a different format from the one in which it is stored. Thus, it can be requested or created in different representations. As long as the specified format is supported, the REST-enabled endpoint should use it. In the preceding example, we posted an XML representation of a watch item, but if the server had supported the JSON format, the following request would have been valid as well:

POST /categories/watches HTTP/1.1
Content-Type: application/json
Host: www.mycatalog.com

{
  "watch": {
    "id": ""watch-abc"",
    "brand": "...",
    "price": {
      "-currency": "EUR",
      "#text": "100"
    }
  }
}
HTTP/1.1 201 Created
Content-Type: application/json
Location: http://mycatalog.com/categories/watches/watch-abc   

Principle 5 – Communicate with resources in a stateless manner

Resource manipulation operations through HTTP requests should always be considered atomic. All modifications of a resource should be carried out within an HTTP request in an isolated manner. After the request execution, the resource is left in a final state; this implicitly means that partial resource updates are not supported. You should always send the complete state of the resource.

Back to our catalog example, updating the price field of a given item would mean making a PUT request with a complete document (JSON or XML) that contains the entire data, including the updated price field. Posting only the updated price is not stateless, as it implies that the application is aware that the resource has a price field, that is, it knows its state.

Another requirement for your RESTful application to be stateless is that once the service gets deployed on a production environment, it is likely that incoming requests are served by a load balancer, ensuring scalability and high availability. Once exposed via a load balancer, the idea of keeping your application state at server side gets compromised. This doesn't mean that you are not allowed to keep the state of your application. It just means that you should keep it in a RESTful way. For example, keep a part of the state within the URI, or use HTTP headers to provide additional state-related data

The statelessness of your RESTful API isolates the caller against changes at the server side. Thus, the caller is not expected to communicate with the same server in consecutive requests. This allows easy application of changes within the server infrastructure, such as adding or removing nodes.

Note

Remember that it is your responsibility to keep your RESTful APIs stateless, as the consumers of the APIs would expect them to be.

Now that you know that REST is around 18 years old, a sensible question would be, "Why has it become so popular just quite recently?" Well, we the developers usually reject simple, straightforward approaches and, most of the time, prefer spending more time on turning already-complex solutions into even more complex and sophisticated ones.

Take classical SOAP web services, for example. Their various WS-* specifications are so many, and sometimes so loosely defined, that in order to make different solutions from different vendors interoperable, a separate specification, WS-Basic Profile, has been introduced. It defines extra interoperability rules in order to ensure that all WS-* specifications in SOAP-based web services can work together.

When it comes to transporting binary data with classical web services over HTTP, things get even more complex, as SOAP-based web services provide different ways of transporting binary data. Each way is defined in other sets of specifications, such as SOAP withAttachment References (SwaRef) and Message TransmissionOptimization Mechanism (MTOM). All this complexity was caused mainly because the initial idea of the web service was to execute business logic remotely, not to transport large amounts of data.

The real world has shown us that, when it comes to data transfer, things should not be that complex. This is where REST fits into the big picture—by introducing the concept of resources and a standard means for manipulating them.