Default HubSpot Blog

REST is not about APIs, Part 2

[fa icon="calendar'] Nov 12, 2013 1:12:40 AM / by Jim Bugwadia posted in REST, Engineering, Cloud Architecture

[fa icon="comment"] 0 Comments

Most articles on REST seem to focus only on APIs. This view misses several key benefits of a RESTful system. The true potential of REST is to build systems as scalable, distributed, resilient, and composable as the Web. Yes, APIs play a role in this but by themselves are not enough.

In Part 1 of this article I described the 6 architectural constraints, 4 interface constraints, and 3 architectural components defined in the REST architectural style. I also detailed why the API centric view of REST merely scratches the surface.

In this final part, I will show how to apply the full REST architectural style, discuss how the benefits are achieved, and provide a way to incrementally migrate to an RESTful architecture.

Applying the basic constraints

Lets try and build a conceptual system from the REST constraints and elements. Our first attempt uses the following constraints:

  • Client – Server: separation of client and server roles

  • Stateless: externalize all data & state (including request state) from the server. We can choose some combination of NoSQL, SQL, or distributed cache data management solutions.

  • Cache: add a cache component to the client, as well as the server

  • Uniform Interface: provide a RESTful API at the server

  • Layered System: the application and data tier are separated into layers

Since we made the application server stateless, we can now add a gateway component for common request management, and scale server instances up & down behind it. The gateway could be implemented using a load balancer or a reverse proxy, and itself can scale up or down as needed. Based on the choice of data management solution, we can also replace the single server with a cluster of data management servers.

We now have a classic tiered architecture and each tier is elastic. This may be good enough for some applications. In fact most current applications use this, or a close variant of this, tiered architecture.

However, this architecture will become quickly difficult to scale and manage in a cloud. Here are a few reasons why:

  • The application server is monolithic; scaling requires deploying the entire application as a separate instance.

  • The failure domain is the entire application. A single bug, or issue, can impact the full application.

  • A single type of data tier is assumed for the entire application. In reality, different modules will need different types of data management services.

  • Incremental changes, that impact only a small set of functions, are not possible to test and manage

To solve these problems we need to further apply the REST constraints on the application tier itself.

The next step would be to further decompose the application server, into multiple RESTful services. Lets say we had two top-level modules in our application, we can make each of them a separate service. A service is now the fundamental unit of deployment and management. Each service is stateless and has its own uniform interface. Each service has its own data cache and storage tier, and these can use different types of data management technologies based on the requirements. A service can also be scaled up or down independently of other services.

The tradeoff with this architecture is that now additional services will be needed to manage the inter-service communication. We can add a service registry to allow services to lookup services. The gateway also needs more intelligence for routing requests and finding services.

Case Studies

Businesses adopting cloud computing have also adopted a RESTful distributed cloud services architecture. Here are a few examples:

  • Netflix transitioned from monolithic tiers to a cloud services approach. They have open-sourced their service registry (Eureka), gateway (Zuul) and several other components. Their engineering blog and the Netflix OSS GitHub repository are great resources.
  • LinkedIn made the transition from monolithic application to distributed services. This InfoQ presentation from Jay Krepps is a great overview.
  • Twitter switched from what they called a “monorails” application to distributed JVM based services. Jeremy Cloud discusses this in an InfoQ presentation, “Decomposing Twitter”.
  • Amazon has not directly presented this, but there are reports of their architecture based on internal APIs and services.
  • Yammer also uses a distributed services based approach, and has open sources a tool called DropWizard to aid in building RESTful Java services.

Applying to Existing Systems

If you are like most developers, it may seem like a stretch to even consider making bold changes to your system to move towards a RESTful architecture. However, the fine-grained services approach has another key advantage. You can leverage the emphasis on modularity to incrementally transform a monolithic application to a cloud services architecture.

You can select an existing module, or when its time to build a new module, built it as a library which can be run as part of your monolithic application or as a separate service.

Summary

If your goal is to build an elastic & composable system - like the internet, you need to learn more than the ‘uniform interface’ constraint in REST. In this article we applied all five required REST constraints, and used different architectural elements to build an elastic architecture where an application is composed of multiple RESTful services. This architecture yields several benefits, and most importantly enables continuous delivery of software. Now small, autonomous DevOps teams can build and manage individual services and get direct feedback on usage! Enterprises can incrementally adopt this architecture by migrating modules in a monolithic application.

Read More [fa icon="long-arrow-right"]

REST is not about APIs, Part 1

[fa icon="calendar'] Oct 1, 2013 3:05:11 AM / by admin posted in REST, Engineering, Cloud Architecture

[fa icon="comment"] 0 Comments

Most articles on REST seem to focus only on APIs. This view misses several key benefits of a RESTful system. The true potential of REST is to build systems as scalable, distributed, resilient, and composable as the Web. Yes, APIs play a role in this but by themselves are not enough. In this two-part post, I will discuss how you can leverage all REST architecture constraints in your systems:

Rest is not about APIs, Part 1: Description of REST and the API-centric view

Rest is not about APIs, Part 2: The true power of REST, and examples of its application

Brief Description of REST

REST (short for REpresentational State Transfer) is an architectural style that describes how a distributed hypermedia system works. The internet (or “the web”) is the best known example of a distributed hypermedia system. The term REST was introduced by Roy Fielding. His doctoral dissertation [1] remains the go-to source on REST from which I have summarized below.

REST is described using 6 architectural constraints, 4 interface constraints, and 3 architectural components.

Architectural Constraints

  1. Client-server: separation of client & server roles i.e. the representation of resources from their stored state.
  2. Stateless: the server should not store or cache client state across requests. Each client request should be transition the stored data from one valid state to another. This allows any available server instance to be used to fulfill any request.
  3. Cache: the server should indicate if data can be cached and reused across requests.
  4. Uniform Interface: all server data can be manipulated using the same interface. This constraint further expands into four interface constraints:
    1. identification of resources: all resources have one or more names (e.g. HTTP URIs) managed by the naming authority (typically the server).
    2. manipulation of resources through representations: The representation of a resource is separated from its identify and can change over time.
    3. self-descriptive messages: the messages should contain metadata that describes how to read the message (e.g. HTTP MIME types and other headers).
    4. hypermedia as the engine of application state (HATEOS): Representations should also contain data to drive application state. This allows clients to be loosely coupled to servers, and require no prior (hard-coded) knowledge of how to interact with a particular resource.
  5. Layered System: each layer deals with the one below it, and has no direct visibility to other layers.
  6. Code on Demand (Optional): the server can extend the client functionality by sending back scripts or code.

Architectural Elements

  • Data Elements: data elements allow information to be moved from where it is stored to where it will be used. Data Elements are described by Resources, Resource Identifiers and Representations.
    1. Resources: are things that can be uniquely named (e.g. a HTML page or image on the Web, or an Object instance in an application.) A request for a resource can return a representation or a set of resource identifiers, or a combination of the two.
    2. Resource Identifiers: are the names given to resources (e.g. a HTTP URL.)
    3. Representations: a representation is what gets transferred between REST components.
  • Connectors: connectors encapsulate the activities of accessing resources and transferring representations.
    1. Client: a Client initiates requests for information.
    2. Server: a Server listens for, and responds to, requests
    3. Cache: a Cache can be attached to clients or servers and is used to speed up interactions.
    4. Resolver: a Resolver helps find resources to establish inter-component communication (e.g. DNS bind)
    5. Tunnel: a Tunnel allows interactions across network boundaries like firewalls.
  • Components: components are the different roles in a system. Components use one or more Connectors for interactions with other components.
    1. Origin server: uses a server connector to manage a collection of resources.
    2. Gateway: a gateway component is a reverse proxy. It performs common functions across servers, such as authentication.
    3. Proxy: a proxy is an intermediary component selected by the client, to perform common functions.
    4. User agent: uses client connectors to initiate requests, and receive resource representations from servers.

The API-centric view of REST

The API centric view on REST focuses only on the uniform interface constraint. For the most when APIs are discussed the assumption is that these are external facing APIs (northbound from the perspective of the application). A RESTful external API is a nice addition for software products, and can fulfill a business need. However, it does not address product maintainability and other architectural challenges like elasticity, resilience, and composability.

The Richardson Maturity Model (RMM) [2] is a popular way of measuring how RESTful an API is. The RMM is useful to qualify whether the API has REST characteristics, but does not imply a RESTful system. ip domain info In a blog post describing the RMM [3], Martin Fowler notes:

“I should stress that the RMM, while a good way to think about what the elements of REST, is not a definition of levels of REST itself. Roy Fielding has made is clear that level 3 RMM is a pre-condition of REST. Like many terms in software, REST gets lots of definitions, but since Roy Fielding coined the term, his definition should carry more weight than most.”
-- Martin Fowler, Richardson Maturity Model

(See [4] for Roy Fielding’s post that Martin is referring to.)

Most RESTful API implementations layered on top of existing systems, have a difficult time with the HATEOS interface constraint. They end up adopting “pragmatic REST” [5]. Getting the HATEOS constraint right requires both the server and client to be designed for this type of interaction, like a web browser and a web server.

If you are trying to add an RESTful API to an existing application, this will be hard to do. However, if you can design for HATEOS the potential payoff is huge as you will have a loosely coupled system, where server-side changes do not easily break the client. [6]

Summary

In this part, we discussed what REST is and why the API centric view is not sufficient. In the next part we will cover how to use all of REST to build a systems as flexible as the web.

References

[1] Representational State Transfer (REST), Roy Fielding, <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm</a>
[2] Richardson Maturity Model, Leonard Richardson Presentation 2008, <a href="http://www.crummy.com/writing/speaking/2008-QCon/act3.html">http://www.crummy.com/writing/speaking/2008-QCon/act3.html</a>
[3] Richardson Maturity Model, Martin Fowler, <a href="http://martinfowler.com/articles/richardsonMaturityModel.html">http://martinfowler.com/articles/richardsonMaturityModel.html</a>
[4] REST APIs must be hypertext-driven, Roy Fielding, <a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven</a>
[5] API Design: Harnessing HATEOAS, Part 2, <a href="https://blog.apigee.com/detail/api_design_harnessing_hateoas_part_2">https://blog.apigee.com/detail/api_design_harnessing_hateoas_part_2</a>
[6] Haters gonna HATEOAS, <a href="http://timelessrepo.com/haters-gonna-hateoas">http://timelessrepo.com/haters-gonna-hateoas</a>
Read More [fa icon="long-arrow-right"]

Subscribe to Email Updates

Recent Posts