Chapter 6

The Key to the Cloud

Restful Services

Life is a distributed object system. However, communication among humans is a distributed hypermedia system, where the mind’s intellect, voice+gestures, eyes+ears, and imagination are all components.

—Roy T. Fielding, inventor of REST

There are many reasons that Representational State Transfer (RESTful) services are a critical component of any cloud solution. First, when building services in the cloud one typically builds on top of an Infrastructure as a Service (IaaS) or Platform as a Service (PaaS) provider or integrates with one-to-many Software as a Service (SaaS) offerings. All of these cloud service providers have exposed their application programming interfaces (APIs) using RESTful services. In addition, clouds are heterogeneous ecosystems that connect many different services from many different companies written in many different technology stacks. The complexities of the underlying stacks and protocols should be abstracted away from the business logic so this ecosystem of services can easily connect and work in harmony.

A great example of this concept in practice is how simply we can plug in social media functionality from Facebook, Twitter, Pinterest, and other social media touchpoints. Underneath those widely used APIs are some very diverse and complex systems. These high-scale systems combine multiple programming stacks, multiple database technologies, and technologies for integration, caching, queuing, event processing, and much more. The beauty of services is that all of that complexity is hidden from us as developers and literally within minutes we can connect our applications and services and leverage all of that wonderful, complex functionality with no knowledge of how the underlying technologies work. That is agility at its finest.

A second reason that RESTful services are a critical component of any cloud solution pertains to the many touchpoints that users consume information on in today’s day and age. Gone are the days of building separate systems for individual touchpoints. Today, the preferred method is to build multiple user interfaces (web, mobile, tablet, etc.) that leverage the same services and are always in sync. We have to build things this way because our users are bouncing around between devices and browsers and will leave in droves if each touchpoint displays different result sets. To make things even easier, there are a few new companies that are delivering mobile platforms so that developers can build a single user interface (UI), and the platforms will transform the code into the various mobile and tablet user interfaces. Did I mention agility?

Third, and most important, cloud infrastructure is virtual and dynamic, meaning resources come and go in an elastic matter and every piece of cloud infrastructure is expected to fail. The cloud is designed to be fault-tolerant so that if any node fails, the system can continue its operations either in a degraded mode or without any degradation if other nodes become available to replace the failed node. To take advantage of fault-tolerant cloud infrastructure, software must be built to be fault-tolerant as well. To accomplish fault tolerance with software, the software must not be tightly coupled to the infrastructure. A key best practice to writing loosely coupled software in the cloud is to store the application state on the client instead of the server, thus breaking the dependencies between the hardware and the software. This concept is a core principle for building RESTful web services.

This chapter will discuss why REST is so important when building cloud architectures. Migrating legacy applications to the cloud can be a challenge. We will discuss what those challenges are and how to deal with them.

Why REST?

Before going much further, this is a good time to discuss REST in more detail. Dr. Roy Fielding, the creator of the architectural approach called REST, looked at how the Internet, a highly distributed network of independent resources, worked collectively with no knowledge of any resource located on any server. Fielding applied those same concepts to REST by declaring the following four major constraints.

1. Separation of resource from representation. Resources and representations must be loosely coupled. For example, a resource may be a data store or a chunk of code, while the representation might be an XML or JSON result set or an HTML page.
2. Manipulation of resources by representations. A representation of a resource with any metadata attached provides sufficient information to modify or delete the resource on the server, provided the client has permission to do so.
3. Self-descriptive messages. Each message provides enough information to describe how to process the message. For example, the “Accept application/xml” command tells the parser to expect XML as the format of the message.
4. Hypermedia as the engine of application state (HATEOAS). The client interacts with applications only through hypermedia (e.g., hyperlinks). The representations reflect the current state of the hypermedia applications.

Let’s look at these constraints one at a time. By separating the resource from its representation, we can scale the different components of a service independently. For example, if the resource is a photo, a video, or some other file, it may be distributed across a content delivery network (CDN), which replicates data across a high-performance distributed network for speed and reliability. The representation of that resource may be an XML message or an HTML page that tells the application what resource to retrieve. The HTML pages may be executed on a web server farm across many servers in multiple zones in Amazon’s public cloud—Amazon Web Services (AWS)—even though the resource (let’s say it is a video) is hosted by a third-party content delivery network (CDN) vendor like AT&T. This arrangement would not be possible if both the resource and the representation did not adhere to the constraint.

The next constraint, manipulation of resources by representations, basically says that resource data (let’s say it is a customer row in a MySQL table) can only be modified or deleted on the database server if the client sending the representation (let’s say it is an XML file) has enough information (PUT, POST, DELETE) and has permission to do so (meaning that the user specified in the XML message has the appropriate database permissions). Another way to say that is the representation should have everything it needs to request a change to a resource provider assuming the requester has the appropriate credentials.

The third constraint simply says that the messages must contain information that describes how to parse the data. For example, Twitter has an extensive library of APIs that are free for the public to use. Since the end users are unknown entities to the architects at Twitter, they have to support many different ways for users to retrieve data. They support both XML and JSON as output formats for their services. Consumers of their services must describe in their requests which format their incoming messages are in so that Twitter knows which parser to use to read the incoming messages. Without this constraint, Twitter would have to write a new version of each service for every different format that its users might request. With this constraint in place, Twitter can simply add parsers as needed and can maintain a single version of its services.

The fourth and most important constraint is HATEOAS. This is how RESTful services work without maintaining application state on the server side. By leveraging hypermedia as the engine of application state (HATEOAS), the application state is represented by a series of links—uniform resource identifiers or URIs—on the client side, much like following the site map of a website by following the URLs. When a resource (i.e., server or connection) fails, the resource that resumes working on the services starts with the URI of the failed resource (the application state) and resumes processing.

A good analogy of HATEOAS is the way a GPS works in a car. Punch in a final destination on the GPS and the application returns a list of directions. You start driving by following these directions. The voice on the GPS tells you to turn when the next instruction is due. Let’s say you pull over for lunch and shut off the car. When you resume driving, the remaining directions in the trip list pick right up where they left off. This is exactly how REST works via hypermedia. A node failing is similar to shutting your car off for lunch and another node picking up where the failed node left off is similar to restarting the car and the GPS. Make sense?

Why are the four constraints of REST so important when building solutions in the cloud? The cloud, like the Internet, is a massive network of independent resources that are designed to be fault-tolerant. By following the constraints of REST, the software components that run in the cloud have no dependencies on the underlying infrastructure that may fail at any time. If these four constraints are not followed, it creates limitations on the application’s ability to scale and to fail over to the next available resource.

As with any architectural constraint, there are trade-offs. The more abstraction that is built into an architecture, the more flexible and agile the architecture will be, but it comes with a price. Building RESTful services correctly takes more up-front time because building loosely coupled services is a much more involved design process. Another trade-off is performance. Abstraction creates overhead, which can impact performance. There may be some use cases where the performance requirements far exceed the benefits of REST and, for that particular use case, another method may be required. There are other design issues to be aware of that are covered in the next section.

The Challenges of Migrating Legacy Systems to the Cloud

One of the challenges companies have when they decide to port applications from on-premises to the cloud is that many of their legacy systems are reliant on ACID transactions. ACID (atomicity, consistency, isolation, durability) transactions are used to ensure that a transaction is complete and consistent. With ACID transactions, a transaction is not complete until it is committed and the data is up to date. In an on-premises environment where data may be tied to a single partition, forcing consistency is perfectly acceptable and often the preferred method. In the cloud, there is quite a different story.

Cloud architectures rely on Basically Available, Soft State, Eventually Consistent (BASE) transactions. BASE transactions acknowledge that resources can fail and the data will eventually become consistent. BASE is often used in volatile environments where nodes may fail or systems need to work whether the user is connected to a network or not. This is extremely important as we move into the world of mobile, where connectivity is spotty at times.

Getting back to the legacy system discussion, legacy systems often rely on ACID transactions, which are designed to run in a single partition and expect the data to be consistent. Cloud-based architectures require partition tolerance, meaning if one instance of a compute resource cannot complete the task, another instance is called on to finish the job. Eventually the discrepancies will be reconciled and life will go on its merry way. However, if a legacy system with ACID transactionality is ported and not modified to deal with partition tolerance, users of the system will not get the data consistency they are accustomed to and they will challenge the quality of the system. Architects will have to account for reconciling inconsistencies, which is nothing new. In retail they call that balancing the till, which is an old way of saying making sure the cash in the drawer matches the receipt tape at the end of the day. But many legacy applications were not designed to deal with eventual consistency and will frustrate the end users if they are simply ported to the cloud without addressing this issue.

What about those mega-vendors out there whose legacy applications are now cloud-aware applications? Most of those rebranded dinosaurs are actually running in a single partition and don’t really provide the characteristics of cloud-based systems such as rapid elasticity and resource pooling. Instead, many of them are simply large, monolithic legacy systems running on a virtual machine at a hosted facility, a far cry from being a true cloud application. It is critical that architects dig under the covers of these vendor solutions and make sure that they are not being sold snake oil.

There is a new breed of vendors that offer cloud migration services. It is important to note that these solutions are simply porting the legacy architecture as is. What that means is that if the legacy applications can only run in a single tenant, they will not be able to take advantage of the elasticity that the cloud offers. For some applications, there may be no real benefit for porting them to the cloud.

Summary

Architecting solutions for cloud computing requires a solid understanding of how the cloud works. To build resilient solutions that scale, one must design a solution with the expectation that everything can and will fail. Cloud infrastructure is designed for high availability and is partition tolerant in nature. Migrating single-partition applications to the cloud makes the migration act more like a hosting solution rather than a scalable cloud solution. Building stateless, loosely coupled, RESTful services is the secret to thriving in this highly available, eventually consistent world. Architects must embrace this method of building software to take advantage of the elasticity that the cloud provides.

References

Bloomberg, J. (2013). The Agile Architecture Revolution: How Cloud Computing, REST-Based SOA, and Mobile Computing Are Changing Enterprise IT. Hoboken, NJ: John Wiley & Sons.

Bloomberg, J. (2011, June 1). “BASE Jumping in the Cloud: Rethink Data Consistency.” Retrieved from http://www.zapthink.com/2011/06/01/base-jumping-in-the-cloud-rethinking-data-consistency/.

Fielding, R. (2000). “Representational State Transfer (REST),” in “Architectural Styles and the Design of Network-based Software Architectures.” Ph.D. Dissertation, University of California, Irvine. Retrieved from http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm.

Hoff, T. (2013, May 1). “Myth: Eric Brewer on Why Banks Are BASE Not ACID—Availability Is Revenue.” Retrieved from http://highscalability.com/blog/2013/5/1/myth-eric-brewer-on-why-banks-are-base-not-acid-availability.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.156.204