Book Image

Hands-On RESTful API Design Patterns and Best Practices

By : Anupama Murali, Harihara Subramanian J, Pethuru Raj
Book Image

Hands-On RESTful API Design Patterns and Best Practices

By: Anupama Murali, Harihara Subramanian J, Pethuru Raj

Overview of this book

This book deals with the Representational State Transfer (REST) paradigm, which is an architectural style that allows networked devices to communicate with each other over the internet. With the help of this book, you’ll explore the concepts of service-oriented architecture (SOA), event-driven architecture (EDA), and resource-oriented architecture (ROA). This book covers why there is an insistence for high-quality APIs toward enterprise integration. It also covers how to optimize and explore endpoints for microservices with API gateways and touches upon integrated platforms and Hubs for RESTful APIs. You’ll also understand how application delivery and deployments can be simplified and streamlined in the REST world. The book will help you dig deeper into the distinct contributions of RESTful services for IoT analytics and applications. Besides detailing the API design and development aspects, this book will assist you in designing and developing production-ready, testable, sustainable, and enterprise-grade APIs. By the end of the book, you’ll be empowered with all that you need to create highly flexible APIs for next-generation RESTful services and applications.
Table of Contents (13 chapters)

Learning about Web 3.0

The following sections focus on Web 3.0 and the evolution and history of web services.

Web 3.0 is generally referred to as executing semantic web, or read-write-execute web. Web 3.0 decentralizes services such as search, social media, and chat applications that are dependent on a single organization to function. Semantic and web services are the primary constituents of Web 3.0.

The following diagram depicts layers of typical Web 3.0 constructs. The semantic web layers are Static Web, Translations, and Rich Internet Applications (RIA) or Rich Web built on top of the internet:

The layered structure of Web 3.0

This data-driven web adjusts according to the user's searches, for instance, if a user searches for architecture patterns, the advertisements shown are more relevant to architecture and patterns; it even remembers your last search and combines the last searched queries as well. Interesting isn't it?

What you see in the following diagram is a Web 3.0 stack, with various building blocks as URI, Unicode representations, syntax (XML/JSON), RDFS taxonomies, and so on; they constitute a Web 3.0 stack:

Let's move on to the web service architecture, the specifications, and the communication protocols, as they are the fundamentals before we move to ROA, SOA, and Representational State Transfer (REST) or RESTful services.

Learning about web service architecture

Web services are a method of communication between two computing devices over a network, and the communication happens in standardized ways (and specifications) for the integration of heterogeneous web applications using XML/JSON, SOAP, WSDL, and UDDI. XML/JSON is the data format that provides metadata for the data that it contains; SOAP is used to transfer data; WSDL is used for defining available services to be consumed, and UDDI will have the list of services available.

Web services architecture (WSA) mandates the presence of certain characteristics, and suggests a few optional ones, when developing any web service.

WSA consists of three significant roles, as you can see in the following diagram, and they are as follow:

  • Service Provider
  • Service Consumer
  • Service Broker

This is shown in the following diagram:

The Service Requestor finds the Service Provider through UDDI, and contacts the provider using the Simple Object Access Protocol (SOAP). The Service Provider then validates the service request and responds to the requestor with XML/JSON as a service response.

Discussing the web API

So far, we have discussed the fundamentals of the client-server/web services paradigm, and the way they communicate with standard protocols; however, we are yet to touch upon REST-based communication and after all, that's what this book is about. This section will cover the introduction of web APIs, and how a web API is a development model for web services. The communication between the devices is REST-based. RESTful APIs do not use/require XML- based web service protocols, such as SOAP or WSDL, to support their interfaces, but they use simplified representations instead.

The following diagram depicts the web API and their simplified representations as the client side and the server side are exposed to each other through high-level interfaces:

So the web API, as shown in the preceding diagram, is available on both the client side and the server side. The client-side interfaces are generally exposed as JavaScript or browser plugins, and the server-side interfaces are generally exposed through the web as JSON/XML. Some of the key terminologies that we will come across concerning web APIs are endpoint, uniform resource identifier (URI), and resources.

The web API is an application programming interface (API) for either a web server or for a web browser. So, Web API is a concept or methodology for accessing any API (available over the web) through the HTTP protocol. There are many categories of APIs, SOAP, XML-RPC, JSON-RPC, REST, and so on. APIs can be developed with any programming language such as Java, .NET, and many more.

So now you have got an idea of what is a Web API is and where REST API development fits into the Web API landscape, let's move on and see more details of SOA, ROA, REST, RESTful APIs, and their key constituents in the following sections.

Learning about service-oriented architecture

Service-oriented architecture is an architectural style of web services. It defines some standards and lays down best approaches to design and develop a web service. Any web service is the logical representation of repeatable business activities that have a specified outcome, such as retrieving a weather report for a particular city, accessing stock prices for a given stock, updating a record to an inventory service, and so on. SOA is self-contained, and also provides guidelines to combine a service with other services as well. Another fact about SOA is that it is a black box (or abstract) to the service consumer who consumes it.

In short, SOA is essentially a collection of services, those services communicate with each other, and a service is an operation or a function that is well defined, self-contained, and independent of other service contexts and states. Services are applications hosted on application servers and interact with other applications through interfaces.

SOA is not a technology or a programming language; it's a set of principles, procedures, and methodologies to develop a software application.

Learning about resource-oriented architecture

Resource-oriented architecture is a foundation of the semantic web (please refer to the Web 3.0 section of this chapter). The idea of ROA is to use basic, well-understood, and well-known web technologies (HTTP, URI, and XML) along with the core design principles.

As we all know, the primary focus of web services is to connect information systems, and ROA defines a structural design or set of guidelines to support and implement interactions within any connected resources. Any business entity can be represented as a resource, and it can be made accessible through a URI.

For example, in an organization's human resource system, each employee is an entity, and salary, employee details, and profiles are associations (descriptors) of that entity.

The following is a quick comparison table for object-oriented and resource-oriented concepts, and it gives a quick insight as to what ROA is:

Objects in object-oriented architecture

Resources in ROA

Every entity is defined as an object

Entities are services

An object has attributes and actions

A service has descriptions and contracts

Objects need to maintain state to interact

Interacts over the network with a defined location or address

Resource-oriented design

The resource-oriented design section intends to walk you through the ROA design guidelines, design principles, and characteristics, along with its properties as well. Having introduced ROA properties, we will look at REST architecture in subsequent sections.

ROA-based web services describe a self-discoverable entity, and modeling is based on its logical form (unlike services, as they are based on the technical form).

Let's look at the basic blocks of ROA such as resources, representations, and so on in the following diagram:

The blocks in the preceding diagram represent the typical structure of ROA and give an idea of how resources are consumed by the service consumers.

Let's briefly consider the concepts and properties of ROA, as follows:

  • Resource providers: Resource providers expose the resources for the service consumers to invoke the services with HTTP methods. Microsoft Azure and Amazon AWS are simple examples of resource providers.
  • Resource: A resource is an explicit reference to an entity that can be identified and assigned and, most importantly, referenced as a resource. Some examples of resources could be servers, devices, web pages, JavaScript, or the latest version of software, the latest defect in software, a directory or list of information about an organization, and so on.
  • Resource name: The resource name is the unique name or identification for the resource. So, no two resources can point to the same data. For instance, the latest version of software is 2.0.9.
  • Resource representation: Resource representation is the useful information about the current state of a resource, specified with a specific format, in a specific language.
  • Resource link and connectedness: Represents (linkage) another resource or the resource itself. Connectedness is all about how reliable and relevant the resource's links are.
  • Resource interface: The resource interface is an interface for accessing the resource and handling its state.
  • Addressability: Addressability is exposing datasets or functionalities as a resource, and the addressability of a resource happens through URIs.
  • Statelessness: Statelessness is maintaining the isolation and independence of client and server states. Every request from the client should be self-contained.
  • The uniform interface: Every service needs to use the HTTP interface the same way, such as GET, POST, PUT, DELETE, and so on. The uniform interface simply means using some common nomenclature that is interpreted the same way across the web. For example, GET does mean get (read) something.

The following table summarizes the HTTP operations that can be used to implement an ROA-based web service:

HTTP operation

Description

GET

Read the resource representations

PUT

Create a new resource

DELETE

Delete the resource (optionally linked resource as well)

POST

Modify the resource

HEAD

Meta information of the resource

The preceding table shows the HTTP methods to implement ROA.

The benefits of ROA

The following are the benefits of ROA:

  • Independent of client contracts: Free from interface agreements/contract formulations, that is, no need to formulate the contact as the entire web is based on HTTP operations.
  • Explicit state: As the resource itself represents states, servers won't receive unknown application specific payloads; the server does not have to keep track of the client who called the server, and also the client doesn't need to know which server it has talked to.
  • Scalability and performance: Scalability with ROA is shown by characteristics such as no contract boundaries, explicit states, and freeing up the clients from the server's stickiness(session). The performance improvement regarding response time for the ROA caching, load-balancing, indexing, and searching play a significant role in improving performance.
A process of creating an affinity between a client and a specific server by a load balancer is called session stickiness.

A contract or agreement is fundamentally a collection of metadata that defines many aspects of an underlying software program.

Beginning with REST

So far, we have looked at ROA and a set of guidelines, such as statelessness, resources, addressability, uniform resources, and so on. Those guidelines are the fundamental implementation of REST architecture. As this book is all about RESTful patterns, we are going to explore more about the REST architectural style in this section.

The REST concepts were submitted as a PhD dissertation by Roy Fielding. The fundamental principle of REST is to use the HTTP protocol for data communication (between distributed hypermedia systems), and it revolves around the concept of resources where each and every component considered as a resource, and those resources are accessed by the common interfaces using HTTP methods:

An example implementation of an ROA/REST service

The preceding diagram shows you where REST stands in the ROA architecture and how it can be accessed by different consumers.

REST is an architectural style and not a programming language or technology. It provides guidelines for distributed systems to communicate directly using the existing principles and protocols of the web to create web services and APIs, without the need for SOAP or any other sophisticated protocols.

The REST architecture is simple and provides access to resources so that the REST client accesses and renders the resources on the client side. In REST style,URI or Global IDs helps to identify each resource. As you know REST uses several resources representations to represent its type such as XML, JSON, Text, images and so on.

REST architecture style constraints

There are design rules that are applied to establish the different characteristics of the REST architectural style, which are referred to as REST constraints:

REST architectural style constraints

The preceding diagram depicts REST constraints in a typical web/internet-based application. The following are the REST constraints:

  • Client-server
  • Statelessness
  • Cacheable
  • Uniform interface
  • Layered systems
  • Code on demand

Beginning with client-server

The client-server architecture or model helps in the separation of concerns between the user interface and data storage:

The client and server

Let's discuss the client and server in the context of ROA as follows:

  • Client: It is the component that is the requestor of a service and sends requests for various types of services to the server
  • Server: It is the component that is the service provider and continuously provides services to the client as per the requests

Clients and servers typically comprise distributed systems that communicate over a network.

The client in client-server architecture

There is no upper bound on the number of clients that can be serviced by a single server. It is also not mandatory that the client and server should reside in separate systems. Both client and server can reside in the same system, based on the hardware configuration of the system and the type of functionality or service provided by the server. The communication between client and server happens through the exchange of messages using a request-response pattern. The client basically sends a request for a service, and the server returns a response. This request-response pattern of communication is an excellent example of inter-process communication. For this communication to happen efficiently, it is necessary to have a well-defined communication protocol that lays down the rules of communication, such as the format of request messages, response messages, error handling, and so on. All communication protocols that are used for client-server communication work in the application layer of the protocol stack. To further streamline the process of client-server communication, the server sometimes implements a specific API that can be used by the client for accessing any specific service from the server.

The service in client-server architecture

The term service used in the context of client-server architecture refers to the abstraction of a resource. The resource could be of any type and based on the one provided by the server (service); the server is named accordingly. For example, if the server provides web pages, it is called a web server, and if the server provides files, it is called a file server, and so on. A server can receive requests from any number of clients at a specific point in time. But any server will have its own limitations about its processing capabilities. Often, it becomes necessary for a server to prioritize the incoming requests and service them as per their priority. The scheduling system present in the server helps the server with the assignment of priorities.

Client-server benefits are in addition to separation of concerns and help with the following:

  • Improving the portability of the user interface
  • Improving scalability by simplifying server implementations
  • Developing with standalone, independent testable components

Understanding statelessness

The statelessness constraint helps services to be more scalable and reliable. Statelessness, in the REST context, means that all the client requests to the server carry all the information as explicit (stated), so that the server understands the requests, treats them as independent, and those client requests keep the server independent of any stored contexts. Keeping the session state within the client is important to manage this constraint in the services.

The following diagram shows the Service Consumer (client) and the Service States are independent and managed within the client and server respectively:

Statelessness (managing states independently)

The statelessness constraint imposes significant restrictions on the kind of communications allowed between services and consumers, to achieves its design goals. The following are the restrictions to achieve statelessness:

  • It is the complete responsibility of the client to store and handle all the application states and the related information on the client side.
  • The client is responsible for sending any state information to the server whenever it's needed.
  • No session stickiness or session affinity on the server for the calling request (client).
  • The server also needs to include any necessary information that the client may need to create a state on its side.
  • HTTP interactions involve two kinds of states, application state and resource state, and statelessness applies to both. Let's see how the statelessness constraint is handled in each state:
    • Application state: The data that is stored on the server side and helps to identify the incoming client request, using the previous interaction details with current context information
    • Resource state: This is referred to as a resource representation, and it is independent of the client (the client doesn't need to know this state unless it is available as response is needed), and this is the current state of the server at any given point in time
The statelessness constraint of REST applies to the application state, that is, being free only on the application state and nothing to do with resource state. Twitter's API is the best example of a stateless service (GET: https://api.twitter.com/1.1/direct_messages.json?since_id=xxx&count=x).

Advantages and disadvantages of statelessness

The following are some advantages of statelessness:

  • As the server does not need to manage any session, deploying the services to any number of servers is possible, and so scalability will never be a problem
  • No states equals less complexity; no session (state) synchronize logic to handle at the server side
  • As the service calls (requests) can be cached by the underlying application, the statelessness constraint brings down the server's response time, that is, it improves performance with regard to response time
  • Seamless integration/implementation with HTTP protocols is possible as HTTP is itself a stateless protocol
  • Improves visibility as each request is its own resource and can be treated as an independent request
  • Improves reliability as it can recover from partial failures

The following are some disadvantages of statelessness:

  • Increase per-interaction overhead
  • Each request of webservices needs to get additional information so that it get parsed (interpreted) so that the server understands the client state from the incoming request and takes care of the client / server sessions if needed

Caching constraint in REST

Caching is the ability to store frequently accessed data (a response in this context) to serve the client requests, and never having to generate the same response more than once until it needs to be. Well-managed caching eliminates partial or complete client-server interactions and still serves the client with the expected response. Obviously, caching brings scalability and also performance benefits with faster response times and reduced server load.

As you can see in the next diagram, the service consumer (Client) receives the response from the cache and not from the server itself, and a few other responses are directly from the server as well. So, caching helps with the partial or complete elimination of some interactions between the service consumers and so helps to improve efficiency and performance (reduced latency time in response):

There are different caching strategies or mechanisms available, such as browser caches, proxy caches, and gateway caches (reverse-proxy), and there are several ways that we can control the cache behavior, such as through pragma, expiration tags, and so on. The following table gives a glimpse of the various cache control headers one use to can fine-tune cache behaviors:

Headers

Description

Samples

Expires

Header attribute to represent date/time after which the response is considered stale

Expires: Fri, 12 Jan 2018 18:00:09 GMT

Cache-control

A header that defines various directives (for both requests and responses) that are followed by caching mechanisms

Max age=4500, cache-extension

E-Tag

Unique identifier for server resource states

ETag:uqv2309u324klm

Last-modified

Response header helps to identify the time the response was generated

Last-modified: Fri, 12 Jan 2018 18:00:09 GMT

For more about cache-control directives. Please refer to https://tools.ietf.org/html/rfc2616#section-14.9.

Benefits of caching

Obviously, there are a lot of benefits to caching frequently accessed data, and the following are the significant ones:

  • Reduced bandwidth
  • Reduced latency (faster response time)
  • Reduced load on the server
  • Hide network failures and serve a client with the response

The cache constraint builds upon the client-server and stateless ones, with the requirement that responses are implicitly or explicitly labeled as cacheable or non-cacheable.

Understanding the uniform interface

As we mentioned earlier in the uniform interface section as part of ROA, REST-based services can use the HTTP interface, such as GET, POST, PUT, DELETE, and so on, to maintain uniformity across the web. The intention of a uniform interface is to retain some common vocabulary across the internet. For example, GET does mean to get (read) something from the server. The services can independently evolve as their interfaces simplify and decouple the architecture, and the uniform interface brings a uniform vocabulary to those resources as well. The following diagram depicts the combination of HTTP Methods and the Resource Names for Uniform Interfaces:

There are four guiding principles suggested by Fielding that constitute the necessary constraints to satisfy the uniform interface, and they are as follows:

  • Identification of resources
  • Manipulation of resources
  • Self-descriptive messages
  • Hypermedia as the engine of application state

We will see each constraint in detail in the following sections.

Identification of resources

As we have seen in earlier sections, a resource represents a named entity in a web application, and it is usually a Uniform Resource Locator (URL). So, an entity can be identified and assigned as a resource by an explicit reference to it.

A URL in a web application is usually a link, and it is in fact a URI. For example, a home page URI, https://developer.twitter.com, uniquely identifies the concept of a specific website's root resource. In REST constraints, the URIs we use are described as follows:

The second method offers similar data to the first method (statuses/retweets) and may produce the same results or combinations, but both methods certainly represent a different resource.
  • URIs bring benefits such as only one way to access a resource, dynamic media types for resource responses (serve the media type at the time it is requested) with the help of the Accept headers, and clients accessing those dynamic resources do not need to change any identifiers if any change is made in the response content type.

Manipulation of resources

Resources, once identified, can be returned by the server in a different format, such as JSON, XML, HTML, PNG, SVG, and so on. These formats are a representation of the identified resources, and the client will understand the list of possible well-defined formats or media types (also called Multipurpose Internet Mail Extension (MIME)) from the headers.

The resource's representation is manipulated or processed by clients. The application needs to support more than one representation of the same resource and the same URI; in other words, the same exact resource is represented by different clients in different ways.

Let's take an example; a document might be represented as JSON to an automated program, but as HTML to a web browser. The purpose of these representations is to provide a way to interact with the resource, and so the clients can indicate the intended representations they wish to receive.

The preceding conceptual distinction allows the resource to be represented in different ways without changing its identifiers. It is possible with the HTTP header (Accept) getting passed to the server by the clients in each request. The resources are updated or added by sending representations from the client by the RESTful application. The following diagram is a sample representation format, captured for a sample request from my Postman tool:

So, the decoupling of the resource's representation from the URI is one of the crucial aspects of REST.

The following list shows various content-type representation formats (as headers) that one can use in the request or response:

  • Text/HTML, text/CSS, text/JavaScript
  • Application/XML, application/JSON, application/x-www-form-urlencoded
  • Image (SVG, JPG, PNG, and so on)
Postman is a tool that helps us to interact with REST APIs. It offers a very friendly user interface that can quickly test the APIs by constructing requests and reading responses. Chapter 6, RESTful Services API Testing and Security of this book provides more information about the Postman tool and its wider abilities to test RESTful APIs.

Self-descriptive messages

A client's request and server's response are messages; those messages should be stateless and self-descriptive. They can have a body and metadata. RESTful applications operate on the notion of constrained message types (GET, HEAD, OPTIONS, PUT, POST, and DELETE) and they are fully understood by both the server and the client.

A resource's desired state can be represented within a client's request message. A resource's current state may be embodied within the response message that comes back from a server. As an example, a wiki page editor client may use a request message to transfer a representation that suggests a page update (new state) for a server-managed web page (resource). It is up to the server to accept or deny the client's request.

Self-descriptive messages may include metadata to convey additional details regarding the resource state, the representation format and size, and even the message itself. An HTTP message provides headers for organizing the various types of metadata into uniform fields. The following diagram depicts a sample request and its headers, and the server response for the same request along with its headers:

So a self-descriptive message in REST style is all about not maintaining state between client and server, and needs to carry enough information about itself or explain with explicit states. So in the following table, you can see the self-descriptive messages with examples:

Resource

GET

PUT

POST

DELETE


booktitles.com/resources

Get all resources belonging to the collection

Replace with another collection

Create the collection

Delete the whole collection


booktitles.com/resources/title18

Lookup for title 18

Modify title 18

Create new resource as title 18

Delete title 18

Hypermedia as the Engine of Application State

Hypermedia as the Engine of Application State (HATEOAS) is one of the most critical constraints; without addressing it, services cannot be termed RESTful services. However, before we get into the details of HATEOAS, let's get a brief idea about the Richardson Maturity Model (RMM) as it is an essential reference and serves as a guide to any RESTful services to follow the HATEOAS constraints.

The RMM is a model developed by Leonard Richardson, and it breaks down the principal elements of the REST approach to Resources, HTTP Verbs, and Hypermedia Controls. The following diagram depicts the RMM's four levels, and those levels are used to grade the APIs; that is, the better the API adheres to these constraints, the higher the scores are:

So, an API is fully qualified to be a RESTful API only when it scores Level-3. We will see more guidelines for how APIs can be RESTful APIs later in this chapter. However, now you know why we touched on the RMM here before we move on to HATEOAS.

Once the client gets the initial response to its resource request from the server, it should be able to move to the next application state by picking up hyperlinks from the same received response.

Let's take an example to explain the preceding statement. Say a client will POST a representation of a new TODO item to the server, then the state of the Task Manager application will change by growing the list of the TODO item and both POST and GET are accomplished via hypermedia links.

Resource representations are shared by sending self-descriptive messages to any identified resources. Then, they change the state of the application, and the client with the received hypermedia links will move to the next application state.

In an HTML browser, GET methods are accomplished by clicking on anchor tags (<a>) that have an HREF attribute, and HREF contains a resource URI. POST methods are achieved by pressing the Submit button within a <form> tag that has an action URI attribute. The anchor (<a>) and form (<form>) tag elements were sent to the client as part of the representation of the client requested resource.

The web contracts (sharing representations) are expressed regarding media types; a client that calls the service would know the media types and how to process the content as well. So the application enables the server to inform the client of possible ways to change its application state via hypermedia.

Some media types work well (in harmony) with the web, and they are called hypermedia formats. The formats that host URIs and links are hypermedia formats.

Plain old XML is not hypermedia-friendly as it doesn't carry the links and protocols.

The following diagram depicts a sample JSON response from a server without and then With HATEOAS (with links and HREFs):

Before we conclude this section, let's have a recap of HATEOAS:

  • HATEOAS means an application state representation (resource) that includes links to related resources. The absence or presence of a link on a page is an essential part of the resource's current state and so is essential for the RESTful APIs.
  • A URI is a differentiator of REST architectural style, and defining the URIs is really critical, as it will be around for a very long time. So it is crucial to evaluate the links (when they change), keeping their future in mind, or put it in a simpler way, the URI should stay the same regardless of the many changes its representations go through. There is an interesting read about this at https://www.w3.org/Provider/Style/URI.html.en; it supports this point in great detail, and we encourage you to have a look.

Layered systems

In general, a layered system consists of layers with different units of functionality. The essential characteristics of layered systems are that a Layer communicates by means of pre-defined interfaces and communicate only with the layer above or layer below, and the layers above rely on the layers below to it to perform its functions. Layers can be added, removed, modified, or reordered as the architecture evolves. Consider the following diagram of layers:

So, let's start with an example. The REST style allows services to make use of a layered system architecture where we deploy the REST APIs on server A, store data on server B, and authenticate with server C. The client calling the REST API doesn't have any knowledge of the servers the services use:

The REST architectural style suggests services can consist of multiple architectural layers. The layers will have published service contracts or intermediaries. The logic within a given layer cannot have knowledge beyond the immediate layers above or below it within the solution hierarchy.

Intermediaries are the layers present between the client and the server and can be added or removed, more importantly, without changing the interfaces between components.

The intermediaries have the following properties:

  • Intermediaries can be event-driven middleware components to establish processing layers between consumers and services
  • They can be proxies (selected by the client to provide interfaces with data translation services, enhanced performance, or security protections)
  • They can be gateways as well (chosen by the server or the network, and used for data translation, security enforcement, and performance enhancements)

A client may not be able to tell whether it is connected to the services directly with the server endpoint, or to an intermediary before reaching the actual server. Intermediary servers help to attain improved system scalability by having load balancers and shared caches. Layers may also enforce security policies for their calling clients.

It would be helpful for us to understand a few applications of layered systems (design), so let's look at the following points:

  • Enables the service clients to invoke the services; the service that is called by the client doesn't reveal any information about other services it's using to process the client requests. In other words, the service consumer (client) only knows about the service it directly calls and doesn't know about other services consumed by the called service to process its requests.
  • The messages between the client and the server are processed by intermediaries helping to free the clients from the runtime message processing logic and making them unaware of how those messages are processed in other layers as well.
  • It's very critical for stability and scalability to add or remove layers in the layered system without any changes to the service consumers.
  • Request and response messages won't divulge any details to the recipients about which layer the message comes from.

While layered systems bring additional latency and overhead as a drawback, there are trade-offs that are the benefits of layers and layered system designs, as follows:

  • Encapsulates legacy services
  • Introduces intermediaries
  • Limits system complexity
  • Improves scalability

Code on demand

In distributed computing, code on demand (COD) is any technology that enables the server to send the software code to the clients to be executed on the client computer upon request from the client's software. Some well-known examples of the COD paradigm on the web are Java applets, the Adobe ActionScript language for the Flash player, and JavaScript.

The following can also be called the advantages of COD:

  • COD is the optional constraint of REST and intends to allow business logic within the client web browser, applets, JavaScript, and ActionScript (Flash). I think video on demand sites are good examples of COD, as the video data files are downloaded and played according to the client system's specifications.
  • Only one optional constraint according to REST architectural style and it is COD. COD allow it clients to be flexible because the server that decides how specific items need to be handled on the client side. For instance, with COD, a client may download action scripts such as JavaScript, Applets (not widely used these days), Flex scripts to encrypt the client-server communication, so the underlying servers won’t aware of any specific encryption methods used in the process.
  • COD can also be applied to services and service consumers. For instance, service design can enable the servers to dynamically defer some portions of logic to the service client programs. This approach of delaying code execution to the client side is justifiable when service logic can be executed by the consumer more efficiently or effectively.
  • RESTful applications may very well be able to utilize clients that support COD. For instance, web browsers can allow servers to return scripts or links that can be executed at the client side. This sort of additional code execution helps to expand the capabilities of the client, without needing the user to install new client software.
  • In the COD style, a client component has access to a set of resources, but not the know-how of how to process them. It sends a request to a remote server for the code representing that know-how, receives that code, and executes it locally.

However, the down side of using COD is reduces the visibility of the underlying API, and not every API prefers these kind of flexibility.

COD is classified as optional; architectures that do not use this feature can still be considered RESTful.

RESTful service mandates

In one of the online discussion forums, Roy Fielding recorded his frustration about a service that claims to be RESTful, but that service is a mere HTTP-based interface. The service was not fulfilling all the necessary REST architecture constraints. He even said that if the Engine of Application State (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API.

With that said, any services that need to be termed RESTful must strictly adhere to the mandatory REST architecture constraints. Those constraints are design rules that are applied to establish the distinct characteristics of the REST architectural style.

Roy, the founder of the REST style, enforces the following REST constraints as mandatory for any web service to be qualified as RESTful. These mandatory constraints are as follows:

  • Client-server
  • Statelessness
  • Cache
  • Interface/uniform contract
  • Layered system
  • The optional REST constraint is COD (architectures that do not use this feature can still be considered RESTful)

Each constraint is a predetermined design decision and will have positive and negative influences on the services. However, these constraints are meant to provide a better architecture that resembles the web (perhaps positive impacts balanced with negative consequences).

There may be a need for potential trade-offs when deviating from REST constraints. Ensure those trade-offs don't weaken or eliminate the mandated constraints. If so, that architecture may no longer conform to REST, or in other words, the services (architecture) are not RESTful.

Architectural goals of REST

The REST architectural style brings a set of properties that help to establish the design goals that are embedded in the application of REST constraints. These properties are as follows:

  • Performance
  • Scalability
  • Simplicity
  • Modifiability
  • Visibility
  • Portability
  • Reliability
  • Testability

The preceding properties signify a target state of software architecture and fundamental qualities of the WWW. Adhering to REST constraints in design decisions helps to achieve the preceding listed goals, and, of course, these properties can be further improved with more design decisions that are not necessarily parts of REST. However, as quoted in the RESTful services mandate section, a web service, to be called a RESTful service, should adhere to the RESTful constraints.