Download as pdf or txt
Download as pdf or txt
You are on page 1of 32

What do you want to learn? Thibault.

Derieuw@stude

Course author

REST Fundamentals Howard

by Howard Dierking Howard Dierking is


Manager on the We
and Tools team at M
Walks through the definition of the RESTful architectural styles and where his current fo
all things Web.
provides an approach for designing systems.

Course info

Resume Course Bookmark Add to Channel Live mentoring


Level Interme

Rating

Table of contents Description Transcript Exercise files Discussion Learning Check My rating

Duration 2
Recommended
Released 21 Mar 2

Introduction Share course

Overview ! "
Hi! My name is Howard Dierking and welcome to REST fundamentals. The word REST has been thrown
around quiet a bit over the last couple years with lots of service providers advertising that they have

RESTful APIs and tool vendors pitching their latest frameworks as the tool for building RESTful
services. However, when you take a look at what's being sold as REST and you compare it to what

REST actually is, you start to see it disconnect, sometimes a pretty big disconnect. And so the purpose
of this course is to step back from focusing on code and instead focus on how to design systems that

meet the definition of REST. Having a good understanding of RESTful design should then give you a
better perspective when evaluating the myriad of technology choices that you need to consider when

designing your own solutions. This first module will focus on two things. First, will set this stage for

understanding what kinds of problems REST was designed to solve. In that we'll consider a few key
developments that are significantly impacting the requirements for a modern distributed architecture.

We'll also take a look at the properties of a RESTful design that can help address these requirements.
The primary goal is that you can make a determination right up front as to whether or not REST is
something that is relevant for you. We'll then spend some time making sure that we have a definition

for REST. Both what it is and what it isn't. Subsequent modules, we'll dive more deeply into the
different aspects. But here, we'll provide the starting point, as well as compare REST to a few other
technologies and approaches such as HTTP, URL, SOAP and remote procedure calls or RPC. Finally,
we'll examine an approach for categorizing applications based on the different architectural

characteristics that they exhibit where each progression is moving closer to a restful architecture. This
model has more recently become a popular tool for understanding REST and has been sited in several
notable books and blogs. So the goal of this module is that if you don't watch any of the other
modules in this course, you'll at least be able to come away with an understanding of what rest is and

whether it might be a good fit for you. So let's get going.

The Need for REST


We'll start out by taking a look at some of the key drivers that can introduce real challenges for a
modern distributed application. The first is heterogenous interoperability which is really just a fancy

way of saying, "I want to integrate applications that are built against different frameworks and run on
different platforms." We then have the rise of devices and finally the move towards the cloud.
Heterogenous interoperability can be illustrated by taking a look at an article on any popular news site.
When you first examine the web page, you'll find lots of different elements on the page that perform
various functions. Everything from site search to sharing the article be a different social networks. In

this distributed service-based architecture, the different providers of functionality cannot make any
kind of assumptions about the platform that each other is running on and yet this kind of broad
integration is only possible if the way in which the different pieces interact with one another is simple,

consistent and reliable. One of the things that we'll see as we look more at REST is that it's based on
this idea of a network-based API rather than a library-based API and this approach makes it a good fit
for integrating heterogenous applications. Now, let's extend our news web site example so that it
supports multiple devices. It's important to note here that device now goes far beyond simply phones

and tablets. For example, you can see that I've included an in-dash navigation system in the illustration
here. In this case, the device might want to integrate with our news application so that it can pull down
traffic related content based on its GPS coordinates or perhaps it even has the capability of reading a
news article to the driver based on the article's text. In any case, it's likely that many if not all of these

devices will serve to only exacerbate that problem of heterogenous interoperability. However, they
also add a new set of problems. First, many devices provide their user experience via natively run
applications rather than through mobile web applications. These are deployed at different times from
one another and at different times from the services that they consume. As such, the services and

client applications all need to be able to evolve independently from one another without running the
risk of making one another unstable. Next, efficiency and performance are big consideration for

devices where the overall network is inconsistent and unreliable and more importantly where many

users pay data charges in proportion to the amount of bandwidth that they consume. Now, the
previous two drivers of heterogenous interoperability and the rise of devices both illustrate the

challenges inherent in building an application that derives its capabilities from the capabilities of lots

of other different providers and one that makes its capabilities available to lots of different types of
consumers. However, what about the sheer number of consumers? For many businesses, the cloud

represents an opportunity to take advantage of something called elastic infrastructure which is both

computing capability and storage capacity that grows and shrinks with the application or applications
that run on it. This can address a number of problems. For example, a service provider is less likely to

run into a situation or a sudden rise in the popularity of a service overruns the overall capacity of the
infrastructure. With the notion of elasticity is also this idea that you only need to pay for the

infrastructure resources that you actually use. So the idea is that you're able to minimize the risk of

having spent money on unused capacity. With regard to scale, the cloud is not a cure-all that will
magically scale all applications infinitely and cheaply. As one article puts it, cloud computing is

extremely powerful because when done right, it can provide great financial rewards as well as

operational rewards but understand that the hardware layer alone is merely a tiny piece of the puzzle
or to put it another way, it is critical to build a scalable architecture in order to take advantage of a

scalable infrastructure. As such, applications that run in the cloud need to be architected in such a way
that they work efficiently both with the elastic infrastructure of cloud providers and the larger

infrastructure of the networks over which they communicate. Now, while scale is certainly important to

some companies, many companies see the primary value of the cloud differently. Specifically, the value
is in moving to this pristine idealized data center shown on the right from the data center that you

have to manage day in and day out, you know, that data center that draws copious amounts of power

requires its own air-conditioning unit to keep cool is the source of regular 2 a.m. pages because a hard
drive failed and one that will overtime need to be continuously upgraded and actively managed. In

reality, that ideal data center probably looked similar to the one that you have to manage. But by

shifting that burden to a cloud provider, to you, it can look like whatever you want it to and that is the
big idea. For companies trying to achieve this idealized data center, there are couple ways in which

software architecture can help significantly. First, the system should be designed such that it does not
depend on complicated middleware which requires constant configuration changes and management

overhead and which is historically had some scale limitations of its own. Secondly, the system should b

designed with transparency in mind so that failure conditions which despite the best architecture will
still happen. When failures occur, they can be quickly diagnosed and corrected.

Architectural Properties
Now that we've established some of the challenges that exist in designing modern distributed
applications, let's take a look at some of the properties of a RESTful architecture. In the upcoming

modules, we'll get in to how these properties are actually achieved in a design but for now, we'll look

at the properties themselves and see how they line up to the challenges that we just discussed. The
first property of a RESTful design is heterogony. This has a definition consistent with the business

driver mentioned earlier. It's the ability of the application to see mostly interoperate with other

participants regardless of language or platform. Next we have scalability. REST addresses scalability in
a couple different ways. First, it limits the amount of complexity that can exist between components in

a distributed system enabling the complexity of the overall system to scale much past the limits of a

more typical application architecture. Second, REST enables an application to more efficiently manage
requests and to scale out horizontally when needed. Next is evolvability. Evolvability describes the

ability of RESTful clients and services to evolve independently of one another as was described earlier
when we were talking about the challenges brought about by devices. Visibility can provide significant

benefits and that it enables value-added components such as monitoring applications or intelligent

gateways to operate correctly without meeting access to any hidden and potentially proprietary state.
A good example of that is session state. Improved visibility also means that a client can more reliably

recover from failures including partial failures and REST enables you to develop rich compensation

strategies for those cases. As I mentioned with scalability, a RESTful architecture enables multiple
components such as proxy servers and caches to participate in the handling of requests. These

intermediaries have the effect of taking load away from your server. Additionally, a RESTful design
keeps your server from having to manage a bunch of shared state and therefor it enables it to manage

its own resources more efficiently and with performance in the same way that caches can improve the

efficiency of a RESTful application, they can also greatly improve the speed in which a response can
be delivered to a user agent. Thereby improving the overall perceived performance of your application.

And finally, and this is based in large part on visibility, a RESTful application can be more easily

managed because the interactions between components happen in a highly consistent and highly
visible way and therefore management tools can have a much greater impact. In looking at how all of

these properties mapped to heterogenous interoperability the rise of devices and the cloud, you can

see that all of these properties are important to at least one of these areas if not all of them. So
hopefully, by now, I've convinced you that this REST thing is something worth taking a look at. So then,

what is it?

Defining REST
Well, let's start out by looking at what it's not and possibly clear up a few common misconceptions.

First, REST is definitely not a new way to use HTTP to make remote procedure calls or RPC. This goes
straight to the heart of a common misperception that REST is inherently any architecture that is not

SOAP. Now, at the end of the day, the mechanics will probably end up with a function somewhere

getting called on a server somewhere. But that's not what I mean when I talk about RPC. In RPC, the

design target of a network interaction is a remote function or a method. And the goal of an RPC

architecture is to abstract a way all of the other details of the network so that while components may
be interacting over a network, those details are completely abstracted away from the developer who's

writing the code. In REST, the design target of a network interaction is a resource which is something

we'll talk about at greater length later on and the semantics around the remote interaction are not

abstracted away at all. In fact, they're made of key part of the design. Second, REST is not HTTP. This

may seem like an odd statement since HTTP is the protocol over which most RESTful interactions

happen. However, it's important to make the distinction because it's not that difficult, and because of
that many people do this, it's not that difficult to write an HTTP friendly application which is

fundamentally not RESTful. For example, a service that makes great use of HTTP verbs does not

automatically qualify as a RESTful service. Finally, REST is not URIs. I think that the over association

came about because of some really great frameworks like Rails and MVC which made it really easy to

design and manage the URL space with routing. Unfortunately, one side effect of this is that many
people I talk to, spend a tremendous amount of energy and angst trying to figure out how to carve out

the perfect URL space when designing a RESTful service and we'll see in future modules that URLs

have their place in REST, however, they don't paint the whole picture and starting with URLs makes it

very easy to slip back in to an RPC way of thinking about your design. So having named a few things

that REST isn't, let's take a quick look at what it is. In short, REST is all about style. It's not a protocol.
It's not a specific implementation design pattern. It's a style of thinking about and designing your

applications. A quick bit of history, it was first introduced by a guy named Roy Fielding and his

doctoral dissertation in the year 2000. However, Fielding had been working on the web and on REST
for nearly seven years prior to his dissertation being published. Fielding was one of the original

developers behind the World Wide Web working on HTTP and the URI specifications and he

developed REST as a way to describe the larger architectural concepts behind how the web was

designed to work. As Fielding says in his dissertation, the phrase representational state transfer is

meant to evoke an image of how a well-designed web application behaves as a virtual state machine
of web pages where progress is made via links.

REST by Comparison
Now, as I mentioned earlier, many people define REST as simply something that isn't SOAP. This isn't

terribly accurate as REST is an architectural style and SOAP is more of an implementation detail. Why
does this matter? Are there RESTful SOAP applications out there? Certainly, none that I'm aware of.

SOAP naturally aligns itself with an RPC design style. It's important to call out the incorrect association

though because believing that REST is simply something that is not SOAP can get in the way of

understanding more fully what REST actually is and that is after all the point of this course. So now

that we've gotten that little point of clarification out of the way, how do REST and RPC compare? The
table here illustrates a few ways in which these architectural styles differ pretty dramatically from one

another. First and probably most importantly, the whole idea of a contract that thing, that forms the

language of how a client and server understand each other is fundamentally different between RPC

and REST. In RPC, as the acronym would suggest, the contract is the service and its procedures. In

REST, the notion of a contract aligns to something known as the uniform interphase, more on that

later. Next, the definitions of available actions are specified out of band in RPC many times using
something like a service description file as in the case of SOAP services. In REST, those actions are

standardized by the uniform interphase and progress through a workflow is made by something called

hyper media. Again, we'll spend much more time in a later module on this concept. Just like with

procedures, the set of all possible errors for a procedure are also specified out of band with an RPC

design. In the case of REST, error semantics are part of the uniform interface. And while you can build
RPC applications that take advantage of caching, this is not something that's guaranteed by the RPC

style whereas it is in the case of REST by way of the commonly understood uniform interphase. In

RPC, procedures are generally called by way of the client knowing the URL for a particular service or

operation. As a result, once the client has been deployed, the server can rarely and if so painfully

change the URL structure for its services. In REST, the server owns all of its URLs with the exception of

a single entry point URL. And clients access individual services by following links. RPC is based around
procedures and procedures have parameters. As a result, an RPC application will almost always

expose some notion of a type system. Sometimes it's a platform neutral type system as in the case of

access D. But there's almost always one there. REST does not have notions of procedures with

parameters, only the idea of media types and media type specifications. As such, there's not a formal

type system that you have to adhere to. Finally, one benefit of RPC, and particularly of some RPC
frameworks like WCF is that because there are effectively self-contained and how they define

application semantics it means that they can tunnel through lots of different protocols, usually with a

simple configuration switch. This is why frameworks like WCF can run on top of protocols like HTTP,

TCP and MSMQ without having to change any of the actual service code. A RESTful system is tied to

the uniform interface of the supporting protocol which right now is typically HTTP. Now I just said a

minute ago that REST is not HTTP. However, HTTP really is the protocol on which most RESTful
systems are built. HTTP provides a simple uniform interphase on which the constraints that define

REST depend. And this really isn't a coincidence. Notice the authors of these two documents, look

familiar?

Demo: Richardson's Maturity Model


The last thing I want to mention in this module is the visual that you can see here called Richardson's

Maturity Model. This way of looking at system architecture has gotten some attention recently with

books like REST in Practice and through authors like Martin Fowler and for good reason. It's a really
helpful tool for seeing where a given architecture fits within the scope of all the concepts that we're

going to be talking about here in this course. From a maturity standpoint, an application starts at level

0 as a set of a plain old XML or POX services and moves up the stack by adapting more RESTful

characteristics until it last it becomes RESTful. One reason I also want to mention this model is
because there's been some confusion around what the different levels represent with respect to REST.

To be clear, level 0 through 3 here represent incremental steps towards REST. They do not represent

different levels of rest. Only in applying hypermedia to your application design, as you can see at level

3, can your design be considered RESTful.

Summary
So let's recap. In this module, we've covered some of the reasons why REST might be advantageous

for you to consider in your designs. We've examined some of the properties that a RESTful

architecture should produce and we've mapped the back to some of the challenges that new trends

and technology are bringing to bear. We then spent some time providing a basic definition for REST as
well as identifying what it isn't and then juxtaposing it with some commonly associated architectural

styles and technologies. My hope is that at this point, we have a clearer picture of whether a RESTful

design style is a good fit for your particular scenarios. In the next module, we're going to see how the

definition of REST is formed through the application of architectural constraints. We'll explore those

constraints in more detail and see how they yield the properties that we summarized here in this
module.

Deriving REST: Constraints


Overview
In the first module, we set the stage by establishing some of the reasons that would make REST an

appealing choice in designing a distributed application. We also established the very high level

definition for REST as an architectural style and then compare and contrast that REST to a few other

styles as well as implementation technologies. In this module, we'll dive deeper into the RESTful
definition. The goal of which is that you can understand how it is that REST is able to achieve the

properties that we discussed in the previous module. The way that we'll accomplish this goal will be to

firstly examine the approach used in defining REST. We'll then walk through each aspect of the

definition so at the conclusion of the module you should understand the method for defining REST, its

definition, and how its definition yields the properties or benefits that we discussed earlier.

Getting to REST
In his dissertation, Fielding begins his discussion of REST by identifying the method that he will use to

go about defining it. He defines this method as being constraints driven as opposed to being

requirements driven. A constraints driven approach is accomplished by identifying the forces that
influence system behavior and then applying constraints so that the design works with those forces

instead of against them. Now that can sound a bit abstract, so I've provided some visual aid to

illustrate the difference between this constraints-driven approach and the requirements-driven

approach. Take the aerial photograph of the Palm Islands in Dubai. This manmade archipelago was

driven by a massive set of requirements. And while it's an incredibly impressive feat of engineering, it

is also a constant challenge to keep the forces of nature at bay, no pun intended. Many software
architectures are built in the same manner. We start out with a small set of business requirements and

design for those. As we get new requirements, we grow our design to incorporate those. RPC designs

tend to take this approach because the domain of the architecture and the domain of the business are

tightly intertwined. Such designs typically focus on solving a programmer problem, for example to

create an abstraction. They're conceived of and tested in a controlled environment and then deployed
into the wild only to discover that there are critical limitations keeping them from being broadly usable

outside of that environment in which they were designed. Conversely, REST was designed by

identifying those forces in a distributed architecture that keep a design from being broadly useable. It
then applies constraints to the working design to incrementally shape it. It is therefore the

responsibility of the application designer to map the domain of the business on to the domain of the

architecture. Put more succinctly, REST is different because it maps the business domain on to the

architectural domain rather than mapping the architectural domain on to the business domain. So if

REST is defined as a result of identifying forces that can be barriers to a distributed application, then
understanding what these forces are can better help understand the significance of the individual

constraints. As I was reading through Fielding's wok to try and extrapolate some of these, I realized

that what I was reading lined up very cleanly to an article that a friend pointed me to a while ago, The

8 Fallacies of Distributed Computing. These are a set of assumptions that developers tend to make

when building distributed applications that usually prove false and as a result yield a failed application.
The list was originally created in 1994 by a guy named Peter Deutsch who worked at Sun

Microsystems. The list consisted of 7 fallacies and was later amended to include one more in 1997 by

James Gosling. I'm using this list of 8 fallacies to illustrate the kind of forces that REST was designed to

take into account. I've also added one more of my own. The first is network reliability. The associated

fallacy is that the network is reliable. It seems so obvious that this is not true. Power outages take

down access points, people trip over network cables, hardware fails, we've all seen this happen. In my

case, I was the guy tripping over the network cable. And even big supposedly robust cloud providers

are not immune from reliability problems. For instance, both Amazon and Microsoft have had some
pretty spectacular service failures in the last year. Yet we still see application after application that is

designed without taking this lack of reliability into account. Latency, the associated fallacy is that

latency is zero. If you've ever deployed an internet facing application where you have users in a

country on the other side of the planet, then you possibly felt the pain that can be associated with this

assumption. However, even if you don't need to support customers all over the world, it's likely that

you will need to support customers who interface with your application via a mobile device. And for

these customers, you must assume that they are on a network that is generally slow and frequently

loses connection to the device. Bandwidth, the fallacy here is that bandwidth is infinite. And while we

have much higher bandwidth capacity than we ever have, the reality is that there are still limits on just

how much information we can fit into a network pipeline. And as it is with latency, this is especially

true for mobile devices, especially considering that even if the customer has the available bandwidth,
they may be incurring a nontrivial financial cost in order to use it. Security, the fallacy here is that the

network is secure. This fallacy like so many others seems obvious when written out here and yet is so

rarely accounted for in a real application. Network topology, the fallacy is that the network topology

doesn't change, which in the world of the internet obviously doesn't hold up to even the most

superficial observation. Servers and clients are in a constant state of moving around. This includes IP

addresses, DNS names, even things that are managed by your server like relative paths and query

strings. All of this change regularly as application scale and this hardware and software is updated

and/or replaced. Administration, this fallacy states that there is only one administrator. Again, it should

be pretty obvious in an internet facing distributed application that there is not nor could ever be a

single administrator. However, so many times we design applications such that it is very difficult for

someone not already intimately familiar with our application to manage it or diagnose an error
condition. In fact, many times, when a remote service fails, you won't even be able to find an

administrator for the failed service. Transport cost. There are a number of interpretations of the fallacy

transport cost is zero. However, the one that resonates most with me could be restated as the cost of

setting up and running the supporting network infrastructure is free. Stated like this, of course this is a

fallacy. You have to pay for network hardware, bandwidth, plus different capabilities like load

balancing. From an architectural point of view, the big idea that this fallacy addresses is that even if an

architecture overcomes all of the other forces listed here, if you can't afford it, it's still not a successful

architecture. Heterogeneous network, we spend a good bit of time reviewing this idea in the last

module. But the fallacy is to assume that all nodes on the network are the same. Of course, we know

that on a network as large as the internet, this can never be the case. However, the reality is that even

on most corporate networks, we have to support a variety of different platforms and frameworks,
particularly with the rise of so many mobile devices. Finally, I've added one more fallacy to this list and

that is the fallacy of complexity. This fallacy assumes that everyone who uses our service has the

proper level of domain knowledge and/or context such that they will use our service correctly. This

fallacy can be seen in designs that require the client to send messages or call functions in a specified
order.

Client-Server
So now that we've taken some time to establish the forces of nature that we want to architect with

instead of against, let's start looking at the architectural constraints that define the RESTful style. We'll

take a consistent method for exploring each constraint in turn. First, we'll look at the constraint itself.

Then we'll see what forces the constraint addresses. And finally, we'll see what properties come out of

applying the constraint. We'll start with the client server constraint. This constraint defines all

interactions between nodes in a distributed architecture as being between a client and a server. The

client initiates by sending messages to the server for processing. The server listens for messages,

performs some processing, and returns a response to the client. The goal of this constraint is

separation of concerns. By separating the concerns of the server and client, particularly for things like

user interface, it means that lots of different types of clients can work with the same server. It also
means that clients can evolve without impacting the services that they consume. Again, the key

principle behind the client-server constraint is separation of concerns. This acknowledges and

addresses a couple of the forces described earlier. Firstly, complexity is managed by the fact that

clients know only about servers and not one another. And servers don't know anything about the

clients that send requests. This separation between clients and servers makes it much more possible to

support a heterogeneous architecture as clients and servers can be built on completely different

platforms using completely different language tools and frameworks. Applying this constraint also

addresses concerns such as administration and security, and then it provides a natural scoping

boundary in the interactions that need to be secured and managed. It also lays the foundation for the

layered architecture constraint that we'll talk about later in this module. Applying the client-server

constraint provides quite a few benefits and the properties that it yields. A few of the notable ones are,
portability of clients, as we've described separating the roles of client and server means that we can

have lots of different types of clients that consume our services. Scalability is achieved by simplifying

the server components, making it easier to add new ones as load demands drive this. Also, as I

mentioned above, applying a separation between clients and servers enables clients to evolve

independently from the servers and services that they use.

Stateless
The next constraint that will apply on our journey of defining REST is statelessness. The stateless

constraint has been around a long time but was given a particular place of prominence in distributed

applications. In fact, I remember hearing about it for the first time in the days where COM (phonetic)

components were going to solve all problems. At any rate, the big thing to note here is that this

constraint is not trying to get you to create an application that has no state. This kind of application

would be incredibly boring and unhelpful. Instead, the stateless constraint here applies to the

communication between clients and servers. To elaborate, the stateless constraint means that the

server should be able to get all the information that it needs in order to process a client request from

the request only, and not from any additional context information that it is responsible for maintaining,
such as, session state. In a system design where the stateless constraint is applied, all session state is

maintained on the client. As you can see in the illustration here, this means that a workflow can

progress between a client and any number of back-end servers without needing to worry about things

like the workflow state being corrupted as a result of synchronization problems between server nodes.

The stateless constraint is all about dealing with the reality that a distributed application exists in a

world where the ground is constantly shifting out from under the application. Sometimes, this

metaphorical ground is actually there and the request from a client can be correctly processed by a

server and return safely to the client. However, this is by no means guaranteed and many times, the

client crashes, the server crashes, or the network becomes unstable before an entire request and

response workflow can complete. This is even truer for longer running workflows that are made up of

multiple requests and responses. Similarly, the stateless constraint is well suited for an environment
where clients and servers are constantly being added and removed where IP addresses and DNS

entries are constantly changing and where intermediaries come and go based on the network path

selected for an individual message exchange between client and server. Additionally, by making state
explicit in the communication between client and server, that state is also available to intermediaries,

which can include management applications, such as intelligent gateways and routers. We'll talk more

about some advanced possibilities for smart intermediaries when we talk about REST in the cloud. But

the key point here is that the stateless constraint is what makes this all possible. Now let's look at

some of the benefits that the stateless constraint can provide. First is visibility, this is the overarching

property gained by applying the stateless constraint, and it's frankly the property that enables many of

the other properties that we'll talk about. Visibility enables all architectural elements that work with

requests and responses to process the messages in isolation from one another without risking state

corruption. Next is reliability, in my opinion, this is the greatest benefit that statelessness can provide.

This is because the state of a given workflow always exists in one place at a point in time. As a result,
any failure in the client, the server, or the network, can be recovered from in a deterministic way. For

example, a failure on the server can be compensated for by the client updating it with the current

state. A failure on the client can be compensated for by getting the last known representations from

the server. Typically, moving the client back one step in the workflow but not corrupting it entirely.

Now, compare this with a design that spreads the workflow state between clients and servers using

something like session state. In that scenario, if either the client or the server fails, the state of the

entire workflow is unknown and the workflow should be restarted. As you consider scaling this

scenario by adding multiple server nodes that must all have synchronized access to this shared session

state, the probability for corrupted state only increases. By constraining communication to be

stateless, the application can be scaled out by simply adding new servers capable of processing the
requests.

Cache
I think that many people associate REST with caching because APIs that use HTTP well end up being

cacheable. However, caching is actually a part of REST's definition. Specifically, and this follows the
previous constraint of statelessness nicely, the cache constraint says that responses from a server

must be explicitly labeled as cacheable or not cacheable. Having these cache declarations as a first

class part of the message means that a RESTful architecture can benefit from multiple levels of

caching, including server caching, client caching, and caching on any intermediary that may sit

between the two. For example, consider a typical web application. Responses can be cached in the

browser on your company's proxy server or anywhere along the path to your origin server. In this case,

it's generally pretty easy to tell whether a request was served from your local browser cache. As in this

case, you'll see no request issued and the HTTP status code of the response will be 304. However, you

can also tell when a response is served by an intermediary cache such as a proxy server by looking at

HTTP's via header. The forces that guide the application of the caching constraints are all related to

the characteristics of any Real-World network. For example, because network latency is never zero,
caching enables clients to completely avoid making some requests and waiting for the responses.

Similarly, because bandwidth is never infinite, getting the data as close to the client as possible can

reduce the number of network segments that data needs to be pulled across. And ideally, the data is

cached locally so that the client doesn't have to consume any network bandwidth. Finally, the cache

constraint acknowledges the fact that there is absolutely a cost for both the client, and the server with

regard to a network interaction. The client for example may be a mobile device where the user is being

charged for the amount of bandwidth consumed. Similarly, the server infrastructure can only sustain a

discrete amount of load before it must be scaled, which naturally comes at a cost, sometimes a

nontrivial cost. Caching addresses these realities, by providing a mechanism to reduce the number of

requests that need to be sent all the way to your origin server in the first place. As such, caching

makes your design more efficient with respect to both latency and bandwidth. These efficiencies then
make your design fundamentally more scalable and that your application simply handles more clients.

Put another way, your application is able to scale out using the infrastructure of the entire network

rather than simply scaling out by growing its own resources. Finally, by caching representations close

to the user, perceived performance can be dramatically improved as the representation is instantly

available.

The Uniform Interface


The Uniform Interface is really the key differentiator between REST and many other architectural

styles. In the early history of the web, consistency between all of the different processing nodes,

clients, servers and intermediaries was maintained only because all of those nodes use the same

implementation library, CERN's libwww. The designers of the web quickly realized that enforcing

consistence semantics by way of a specific implementation, which was of course coupled to language

platform, et cetera, that this was not a scalable solution, and therefore the Uniform Interface constraint

was developed and applied in order to help the web scale quickly and reliably. The purpose of the

Uniform Interface is to apply the more general software design principle of generality to the

communications between distributed components. And as you can see here in the diagram, applying

the Uniform Interface constraint means that all the nodes in this design, whether they're a client, a
server or anywhere in between can communicate with one another via a standard mechanism. ( Pause

) Now the entire next module is devoted to the Uniform Interface. But because you'll hear these terms

used a lot in reference to REST and even HTTP, it makes sense to provide a basic definition here. First,

a client consumes service capabilities by interacting with 3 sources. Resources are identified by

resource identifier, in HTTP terms this is typically a URL. While a client interacts with resources, the

client works directly not with the sources but with representations of those resources. For example, I

am a person and I can be identified by something like my name. However, if you're a software

program, you won't fetch and work with me, at least I hope not, instead you work with an XML or

JSON representation of me. In addition to the requirement that communication in a RESTful system be

stateless, the constraint of self descriptive messages means that a message should also contain the

metadata needed for a client or server to actually do something with it. Put another way, statelessness
makes the state available to the components. Self descriptive messages make the state intelligible.

Finally, the hypermedia constraint gives servers and clients a way to truly be decoupled from one

another by enabling clients to progress through a workflow by following server generated links, much,

much more on this in the next module. Like I mentioned, the big deal behind the Uniform Interface is

applying the principle of generality to network interactions between distributed components. This is in

response to several of the forces mentioned at the beginning of this module. The first is that the

network is not reliable. Therefore, it's important that all components involved in processing request

and serving a response understand message semantics in the same way. This is so that they can both

take advantage of optimization opportunities, as well as gracefully handle error conditions. In addition

to the network being unreliable is the fact that the shape of the network is constantly changing and

providing a Uniform way of handling communication enables new innovations to be developed and
tested, as well as enables existing components to be reliably improved. The reality of decentralized or

nonexistent administration is addressed by the Uniform Interface and that the semantics of any

interaction are well known to any node on the network, enabling mitigations to be developed in the

event of a failure, even without having a phone number to call. At the very least, the semantics defined

by the Uniform Interface should tell the person handling the failure whether or not they need to search

for that phone number. Most importantly in my opinion, the Uniform Interface acknowledges the

reality that applications on the web are written in all sorts of different programming languages and

they run in all kinds of different environments, different platforms and on different frameworks.

Ensuring that all those need to only understand the Uniform Interface has in my estimation been the

principal reason for the exponential growth of the web. Finally, and closely related to that previous

point, the Uniform Interface acknowledges the reality that RESTful applications will consist of
components written by lots of different people in lots of different ways. And that ensures that no

component in a distributed application needs to understand the internal implementation details of

another component. To put it in service-oriented architecture terms, the Uniform Interface is the

contract between clients and servers. Now there are ton of benefits that the Uniform Interface

provides, pretty much every force that the Uniform Interface addresses brings along with it more than

a couple benefits. However, 2 that I'll call out here because they're a kind of umbrella benefits are

visibility and evolvability. Visibility is that property that ensures that a message means the same thing

to every component involved in processing it. There are a ton of benefits that fall out of this, from the

ability to reliably innovate, to the ability to support an unbounded number of different platforms.

Evolvability is a property of the Uniform Interface that enables all nodes in the system to be improved

or replaced entirely without causing the system to become unstable. To summarize, the Uniform
Interface constraint is a really big deal, so big in fact that we're going to spend the entire next module
focusing on it.

Layered System
Earlier on this module, we talked about how the stateless constraint improved visibility for all nodes

involved in the communications between clients and servers and that improving visibility improved
things like reliability and scalability. We then apply the Uniform Interface constraint and gain generality,

ensuring that all components communicate with one another in the same way. We can then build on

this foundation and apply the layered system constraint to help further manage complexity and

thereby scale the reach of our design, pass the boundaries of what could be manage by any single

group of people. Similar to that of software component architecture, the layered system constraint

says that a component in a system can only know about the components in the layer with which it is

interacting. Applying this constraint places a fundamental limit on the amount of complexity that you

can introduce to a system at any given layer. The tradeoff for applying this constraint is that you can

introduce latency, since after all, strict layering means that a message will likely have to travel through

more intermediary nodes than in the case of a direct connection. This can be mitigated, however, with

specialized intermediaries such as shared caches and load balancers as shown here. Again, the layered
system constraint is driven by the principle of simplicity and in context, simplicity here is directly

related to the reality that the network infrastructure between and including the clients and servers of a

distributed system are constantly changing. Enforcing strict layering limits the scope of impact that

even significant changes in one layer can have on all of the other components in the system.

Additionally, a layered system addresses the reality that the network is not secure, and that each layer

represents a potential security boundary whereby an administrator can mange unique security policies

for the components in that layer. The natural benefit that comes out of applying the layered system

constraint is that the whole system can scale far beyond the limits of any system that is managed by

any centrally managed group of administrators or resources. The modern web is a prefect illustration

of this benefit in action. The web has no central administration. My web browser is managed by me. It

knows how to communicate with my corporate proxy which is managed by my company. That proxy
knows how to communicate with its internet service provider which is managed by some other

telecommunications company and so on. Each layer of the system is managed by different people and

has different policies. But as a result of the Uniform Interface, they all communicate in the same way

and because of this, I don't need to know or care about anything past how I point my browser at my

proxy server, and it is this combination of simplicity in scale that enables me and 2.2 billion other

people to all connect and use the internet.

Code-on-Demand
The code-on-demand constraint doesn't end up getting talked about as much and talks on REST, in

large part because it's listed in Fielding's paper as an optional constraint. And it's optional for good

reason, and we'll talk about that in minute. That said, I also think that it's been ignored somewhat

because there were several years were there wasn't a technology that proved ubiquitous enough to

make it worth applying it, at least not outside of an internal more centrally managed system. However,

with the continued growth of rich web client applications, think HTML5, jQuery, AJAX, et cera. And

with the emergence of JavaScript applications which are independent of a web browser, think node.

The code-on-demand constraint may prove advantageous as it relates to script. Before I get too far
ahead of my self though, let's define the constraint. As shown here, the constraint says that in addition

to delivering data and metadata, servers can provide clients with executable code. The primary force

driving the code-on-demand constraint is complexity. And therefore, the primary benefit provided by

the constraint as I already mentioned is simplicity. The idea is that clients can download readymade

features and not have to write special and possibly redundant logic. Now all that said, the benefits

provided by the constraint don't come without tradeoffs. And the tradeoff here is a pretty big one.

Having the client download and execute readymade features can greatly reduce visibility which can

have a negative impact on things like caching and manageability. Not to mention the security risks

associated with downloading and running code that you may not control. The key takeaway for what

to do with this optional constraint is this. It's fine to apply code-on-demand. However, you should

apply it in such a way where it adds value to the design for clients who support it, but then it doesn't
break clients who don't support it. A good example of the constraint is found in the world of passive

identity federation. Think of the case where an application delegates authentication responsibilities to
an identity provider like Google or Facebook. As a part of a federated workflow, one server returns a

response where the expectation is that the user agent will issue an HTTP post to another server.

Because a post request can't be initiated as the result of a redirect, the server returns in the response

and HTML form along with some JavaScript code to automate submitting it. However, in the event that

script support is disabled in the user agent, the response also contains instructions so that a user can

submit the form. Again, clients that support code-on-demand are simplified, while those that don't

have an alternate way to make progress.

Summary
In this module, we've gone deeper into definition of REST, seeing how it's the result of incrementally

applying constraints rather than building it up from requirements. We then explored each of the

constraints in detail, looking at the constraint, the forces that guide its application and the properties

or benefits that it can provide to the overall architecture. In the next module, we'll see how these

constraints, particularly the Uniform Interface, form the vocabulary that we'll use in designing RESTful

systems.

Elements of RESTful
Architecture
Overview
In the last module, we spent a lot of time looking at the constraints that make up the definition of
REST. In this module, we're going to pay special attention to one of those constraints, the uniform

interface and we'll see how it provides the key architectural elements that we'll use in the process of
designing our own RESTful systems. Like I mentioned, the primary focus of this module will be on the

additional constraints that make up the uniform interface. You can see those covered in bullet points 2
through 5. However, we're going to spend a few minutes upfront talking about two important

elements that are used throughout the discussion. In fact, you've probably already heard them
mentioned in the last module. Those are connectors and components and they describe how various

pieces of a distributed architecture are organized and relate to each other via the uniform interface.

Components and Connectors


In REST, the various software elements that interact with one another are called components. And

they're organized by the role they perform in the overall system. Fielding defines four major
components types in his dissertation. Most of us are already used to the first two. An origin server is
the ultimate destination that listens for requests and returns responses, sometimes with

representations. One important thing to note from the REST perspective about the origin server is that
it owns the URL name space for all of its resources. We'll talk a lot more about that little bit later.

Similarly, most of us have a pretty good concept of the user agent component type. In fact, we likely
hear the term and immediately think of a web browser which is without a doubt, the most common

example of a user agent. A user agent is responsible for initiating a request or a state transition for
resources. The last two component types are common intermediaries in a modern web architecture,

that is they sit somewhere in between a user agent and an origin server to provide various kinds of
additional processing from cashing to load balancing. The key distinction between a proxy and a

gateway is that a proxy represents multiple user agents to the network. And as such, the client
determines whether or not it will use a proxy. A gateway on the other hand represents multiple origin
servers to the network. On the web today, there can be multiple layers of these intermediaries

between a user agent and an origin server. Now we've identified components as being the units that
work together in a RESTful design. Connectors can be thought of as the set of possible interfaces that

a component can implement to accomplish its work. They're categorized by the role that they perform
for a given component. Like user agents and origin servers, client and server are the most common
types of connectors. A client connector initiates a resource request or a state transfer. A server

connector listens for a request and responds. A cash connector, not surprisingly, manages a store of
representations that can be reused for a specified amount of time and can directly respond to request

for those representations. The last two are interesting, or at least they were for me. A resolver
translates a resource identifier into whatever the right address format is so that two components can

make a connection. A great example that Fielding uses of a real world resolver is how DNS translates a
URL host name into an IP address which is necessary to initiate an actual TCP connection. TNS is just a
well known example though. A resolver can be anything that translates something into an address that

can be used to initiate a connection. The nice thing about using resolvers is that they provide a level of
indirection between components and thereby extend the lifetime of a reference to a component. This

is important when you take into account forces such as the fact that the network topology is always
changing. Using the previous example, DNS enables the underlying IP address of a component to

change without breaking the reference that another component may have to it. Finally, a tunnel
connector relays communication across a boundary. A good example of this on the modern web can

be seen and how proxies deal with SSL. In the event of a connect request, a proxy will switch to a
tunnel for further requests. This is because SSL doesn't allow proxies to participate for obvious

security reasons. One key thing to point out in the relationship between components and connectors is
that a component can implement multiple connectors. For example, an intermediary such as a proxy
implements at least the client and sever connector and it may vary like implements all of the

connectors listed here. Like I mentioned a few minutes ago, this module is focused on REST's uniform
interface constraint. This is the constraint that Fielding believed best differentiated REST from other

architectural styles. And the constraints that define the uniform interface are probably the most
practical when it comes to designing RESTful systems. So, looking quickly through the uniform

interface constraints, you can see that we'll need to understand about resources, representations,
messages and then possibly the worst acronym in the history of acronyms, "Hypermedia as the Engine

of Application State."

Resources
Let's start with resources. These are the philosophers of the RESTful elements, their concepts, not

entities like rose on a database, not even specific values, they are concepts. In more academic
language, a resource is what the author intends to identify rather than any specific value. Another

description that resonates with me is to say that a resource maps a concept to a set of entities over
time. So while a resource is not an entity, a resource is related to entities and the relationship between

a resource and entity is many to many. For a while, I had kind of a hard time coming to grabs with
what this practically meant for a design. I think this was largely because when I would give talks on
REST, my focus was always in juxtaposing a resource with a representation, more on representations

in a bit. And so, I would regularly use the example of well, me. The example was, as I've mentioned
earlier, I'm an illustration of a person resource and I can have many different representations such as a

photograph, a business card and so on. And while this is a fine way to illustrate the difference between
a resource and a representation, it made it more difficult for me to truly understand the mapping

aspect of a resource, and this is because my example always map a single resource to a single entity,
me. I needed a better example. So, I extended it out to include my family. If you look at the graph here,

you can see that I have a few resources listed out. As you can see, this represent concepts like
youngest child, it's not entities. One thing to point out here is that it's perfectly valid for all of these
concepts to exist even when they don't have any actual entities mapped to them. When we introduce

the entity Grace (phonetic), my oldest daughter, you can see that we now have a mapping. In this
case, the mapping is between all of the concepts on the left to a single entity Grace. At the time of her

arrival, Grace is my only child, my youngest child and my oldest child. Additionally, she has her own
conceptual identity. Now, when Sarah (phonetic) came along, notice how the map changed. My

children resource now points at two different entities. Also notice that at this point in time, while the
concept of youngest child hasn't changed, and this means that the resource hasn't changed, the

mapping between the resource and the entity that it maps to has changed. It's changed from Grace to
Sarah. And then just to drive the point home, notice how the map here changes when Abigail

(phonetic) comes along. The children resource now maps to three different entities. The youngest
child resource now maps to Abigail. In all of the changes, Grace has remained oldest child and each of
the kids have their own conceptual identity. The key point here though is that a resource itself is a

concept and it should be a pretty stable concept in a system. What can and should change over time
is the mapping between resources and the entities which form the values for those resources. One

way that I've seen a design grow overly complicated and frustrating for the designer, is when the
designer models resources as entities. This yields a fine grained explosion of relatively unstable

resources.

Resource Identifiers
If a resource is a unique concept in a system, it seems only fitting that it should have a unique

identifier. The resource identifier then is how a server makes a resource available for interaction. Now, I
said in the previous slide that a resource should be a relatively stable concept. And that translates here

to say that a resource identifier should not change very frequently, though the mappings to
underlining entities may very well be changing constantly. Additionally, while the mappings between
entities and resources may change, the server is responsible for ensuring that the mapping is

consistent with the meaning of the resource. Since after all, a resource is a concept. To use the
example again of my family, it would change the meaning of the children resource if I were to suddenly

start mapping that resource to pet entities regardless of how I feel about my pets. So, as we talked
about a minute ago, a possible resource map of my family might look something like this. If I were

building a RESTful system on HTTP and wanted to create identifiers for all these resources, it might
look something like this. Here, I'm using URLs to identify the resources. I've created a resource

hierarchy here with children at the top and resources like youngest and oldest as well as resources to
identify each child. Now, if you're a database type of person, you might question whether or not it was

wise to use the first names as the resource identifier and not a surrogate key. While there is absolutely
nothing wrong with using a surrogate key to identify a resource, I deliberately chose to use first names
here to remind you not to think about resources from an entity perspective. Now, when you're building

RESTful systems on top of HTTP, you'll be using URLs to identify your resources and there are a couple
of tools for accessing them. Scott Allen recently released on Pluralsight a great course on HTTP

fundamentals, where in it, he showed this first tool called Fiddler. Fiddler is a fantastic tool that among
other things lets you do two things that are really helpful when building and testing RESTful systems.

First, it lets you monitor the communication between your client and service. It does this because it is
an example of a proxy component, so it can sit between your user agent and your server and it

functions as an intermediary to simply display the messages passing through it. The second function
of Fiddler is that it allows you to create HTTP messages from scratch and send them to the server and

then analyze the response. So in this capacity, Fiddler acts as a user agent. Another tool that you can
use to create and view HTTP messages is a command-line tool called cURL. This tool is probably more
popular in the Unix World but it absolutely runs on Windows and again, it's a very light weight user

agent component that you can use to initiate requests or state transfers to a server.

Resource Metadata
One thing you'll see is we walk through the various elements of a RESTful design is that there's a lot

different types of metadata that are an explicit part of an inter-component communication. This goes
back to ensuring that the system has a high degree of visibility as we discussed back in module 2 with

the stateless constraint. The first type of metadata that we see is metadata about the resource itself.
Now in HTTP, nearly all types of metadata end up being flattened into the same place in a message

exchange and this is in the HTTP headers. So whether or not a header qualifies as a specific type of
metadata is really a matter of looking at it and determining what it's actually describing. In this case,

you can see that in the message exchange, I've bolded two headers, the location header and the ETag
header. Both of these headers tie very directly to the resource itself. The location header here is a link

and is the actual resource identifier. The Etag represents the state of the resource at a point in time
and can be used in scenarios like checking to see whether on not an item can be served from a cache
even after its cache lifetime has expired. It can also be used to implement an optimistic concurrency

strategy. For example, update the resource only if the ETag value has not changed. This would mean
that the state of the resource had not changed.
Representations
Now, if a resource is a concept, a representation is something concrete that, well, represents that
concept at a point in time. According to Fielding's definition, a representation is really just any
sequence of bytes and there can be multiple representations for any given resource. As we'll see in just

a bit, a representation can be tied to a bunch of different pivots or dimensions, not just the format
which is what we most often think off when we think about representations. Now, it's great to have

this separation between resource and representation as well as to have the ability to have different
representations for a resource but it bears asking the question, why do we need this capability? There

are two answers. The first reason is found in the nature of a resource. If a resource is an abstraction
and functionally a map to a set of entities that change over time then there is really not a good way to

manipulate that resource directly. It doesn't really exist concretely as something that can be
manipulated. Also, the need for potentially multiple representations ties back to the very beginning of
this course when we talked about heterogenous interoperability. And in an environment like the web, a

service needs to support lots of different types of clients. Each with a different set of capabilities and
expectations, and even those change over time. Representations provide the ability for servers to

smoothly navigate this consistently shifting landscape. Finally, the process of ensuring that a client
gets the best possible representation is called content negotiation. There are different categories of

content negotiation and within those categories, there are different strategies for design and
implementation. However, the two categories are server driven and agent driven. In server driven

content negotiation, the server makes a decision about the representation sent to the client based on
information in the client request. Remember that we want to ensure that we keep to the stateless

constraint and keep everything nice and visible. In agent driven content negotiation, the user agent
and the server worked together to determine the best representation. Now, this could mean different
things but it typically means that the server provides the user agent with a set of choices in the form

of links and the user agent dereferences one of those links. In the same way that we talked about
resource metadata, representation metadata is simply data that's a part of the message that describes

the representation. Again, in HTTP, it shows up as a part of the standard HTTP headers. So you'll need
to look at the individual header to get a feel for whether or not it's describing the representation. The

goal of this metadata is to help the clients and servers know what to do with the otherwise opaque
byte stream that they're handed. So let's take a look at representations, representation metadata and

content negotiation in action. Consider the following HTTP request, I've bolded some of the different
headers that qualify as representation metadata as they specify this clients preferences. As you can

see, the client would like to work with the JSON format which it declares by adding an accept header
with the value of the JSON media type application/json. Media types which are also called content
types are the standard way that representation formats are communicated in the web architecture.

Nearly all of the formats that are core to the web like JSON are registered with an organization called
IANA which stands for the Internet Assigned Numbers Authority. Additionally, you're free to create

your own media type definitions though there are some naming conventions that you should follow.
Check out the IANA website for more details on those conventions. At any rate, here we've specified a

preference for JSON, we've also provided some information around the types of encoding, languages
and character sets that our client knows how to deal with. We can then send this request over to the

server at which point will get the following response. Now, notice in this exchange that the server
simply returned a JSON representation. My client knows this because of some representation

metadata in the response, notably, the content type header. This is an example of server driver content
negotiation. In the case of agent driven negotiation, the server might still return JSON if it knew how
to generate it but it may also send me back a list of links that I could dereference to get my resource in

a different format. In fact, let's see what would happen if I wanted a different representation for that
same resource. In this case, let's say that I wanted a picture of the Grace resource. I can simply change

the representation metadata on the request as you can see here with the accept header, and because
my server is capable of generating a PNG representation, I get a binary stream back along with the

representation metadata of the standard image PNG media type. And because my client knows how
to process this media type, I can then display a very cute image to my user.

Control Data
Now, in adhering to the stateless constraint and ensuring that we have visibility in inter-component
exchanges, we've talked about metadata for both resources and representations. This helps clients and

servers know how to properly identify, locate and work with resources. However, what about all of that
other stuff like letting a server know what to actually do with the representation, or letting the client

know whether a request succeeded or failed. Remember that to be stateless, all of this information
also needs to be a part of the uniform interface. Or, to put in other way, the messages should be self

describing. Control data is the term that Fielding uses in describing this kind of information which is a
part of the message exchange between clients and servers. It can be used to describe an intended

action, the meaning of a response or override the default behavior of a connector. Let's jump back
over to HTTP and take a look. Similar to the different types of metadata, control data exist for both

request and responses in HTTP. For example, consider the following HTTP request, two pieces of
control data to point out here are the get method which tells the server how to process the request
and the If-None-Match header. This turns this get request into what's commonly called a conditional

get request. As I mentioned in the previous slide, one of the things that control data enables you to do
is override the default behavior of a connector, and this is true in the case of the If-None-Match

header. It overrides the default behavior for handling get request and enables the server to produce a
header only response if the value of the state of the resource has not changed. Then, let's look at the

control data on the HTTP response. The most obvious data element is the status code. In our case, we
return it to 100 status code indicating success. However, there are many other status codes that

provide a rich set of semantics that we can use in designing components. In addition to the status
code, we can see another great example of control data in the cache control header. This header

provides instructions to a cache connector either on a user agent or any intermediary component with
information on how long the response can remain stored in that cache.

Hypermedia
The last constraint of the uniform interface is hypermedia. In my opinion, this is one of the most
important constraints of the REST uniform interface because it's the one that most differentiates a
RESTful design from and RPC design. Without hypermedia, it's still pretty easy to slip into an RPC

design or a service structures it's URLs into resource hierarchies, makes proper use of metadata and
control data and even enables multiple representation formats and content negotiation. If you

remember from module 1, this kind of service if described by Richardson's maturity model as a level 2
service. This kind of service is not necessarily a bad design. In fact, this kind of design is likely

representative of the overwhelming majority of currently deployed services. It's just not a RESTful
design, as hypermedia is a constraint of the uniform interface. So what's the big deal about

hypermedia then? Fundamentally, hypermedia is about dramatically reducing the coupling between a
client and server. And by coupling here, I'm talking about a more implicit type of coupling. Specifically,

hypermedia decouples a client from having to know the URLs of all the different resources that a
service exposes. Instead, a hypermedia client should only need to know about a single entry point URL
and should then be able to dereference links to interact with the other resources in the system. For

example, let's revisit the online new site that we talked about back in module 1. It's highly unlikely that
you find an article on a news website because you have foreknowledge of every page contained within

that site. Instead, you navigate to the website's home page and you follow a link to an article that's
relevant or interesting to you. Or, perhaps, you enter some keywords in a search box and click Submit.

Both are valid examples of a hypermedia driven workflow. So hopefully, you can see that hypermedia
is important to protect the client from having to know about a potentially prohibitive number of

resource URLs. But it's also important to protect the server from getting locked in to a specific URL
structure because a client or a few million clients have taken a dependency on a fixed structure at

some point in time. As we said in module 2, one of the forces that REST was design to work with is the
fact that the network topology is always changing. As such, the server needs to unilaterally own its
own URL name space. Without hypermedia to drive clients through workflow, this name space ends

up being jointly owned between the server and potentially lots of different types of clients making the
evolution of the server difficult to impossible. I mentioned earlier that hypermedia is probably the most

overlooked constraint in REST, and I think the reason for this is that people have too narrow of a
definition for what it is. And as such have a difficult time seeing how it could possibly be sufficient for

guiding a client through all of the various and possibly complex workflows in there system. And if you
consider this first example, it's not difficult to see how this opinion could be formed. This link is one of
the simplest and most common examples of a hypermedia control in the HTML media type. Now, I

mentioned the media type deliberately here because I want to drive home the point that some media
types like HTML already include hypermedia related language elements. These are called hypermedia

controls. Other media types like XML and JSON which are arguably the most frequently used when
building services are structural in nature and they don't by themselves include any hypermedia

controls. This means that as a service author, it's your responsibility to either choose a media type that
already has hypermedia controls or design a format which can include hypermedia controls. Now,

back to the anchor tag displayed here, there are really two elements to mention. The first and most
important is the rel attribute. This is used to identify the link relationship and it's what gives meaning to

the link. To put it another way in the interest of making things a little more concrete, a client should not
need to understand anything about the URL value of that href attribute. Instead, the client should be
written to know only about the possible link relationship values and then on activating a control,

simply follow the associated URL. We'll see much more about this when we talk about building
RESTful clients in module 5. Now, this kind of hypermedia control is only good for get request. But

what if I want to update a resource? The HTML media type provides additional hypermedia controls
for creating and transferring representations. Here, you can see using the form in input elements. For

me, this was the moment of realization where I started seeing hypermedia in a more complete context.
In this example, I'm using the HTML class attribute as the place to declare my link relationship and this

is because the form element doesn't have a rel attribute. The action attribute specifies the resource
URL to address when the control is activated. And I'm also declaring the HTTP method to use for

accessing the resource. I didn't have input elements to allow the client to fill in the values. And it
should be pointed out here that the client doesn't have to be a human client. And at the end of all that,
I transfer the state to the resource specified in the option attribute. Now, also keep in my mind that

forms, even in HTML don't have to use post when submitted. If I were to specify "get" as my method
here and test it in a browser, the name value pairs for my input elements would be transferred to the

server as querystring parameters. Finally, while I've been talking about hypermedia as it relates to a
representation format, there are media types that are not text based and would therefore have a

problem conforming to these examples. In such cases, it's also possible to include hypermedia controls
as a part of the representation metadata that we talked about earlier. For more information about this

in HTTP, look for the HTTP link header proposal that is part of RFC 5988.

Types of Hypermedia
So as you saw in the previous example, hypermedia is much broader than simple links that fetch

representations. The table here reflects a categorization scheme written about by Mike Amudsen in his
book, Building Hypermedia APIs with HTML5 and Node. Because HTML is arguably the most

hypermedia aware type that we have today, not to mention, it's the one that nearly everyone is familiar
with. The examples for the different types here are shown in HTML. As you can see, links can be used

to embed one representation within another as in the case of an image element. Naturally, links can
also be used for getting representations as in the case of the HTML A element or anchor element as
well as a form element within an action of "get" as we talked about just a second ago. The last two

links are I think more interesting. An idempotent link is one that will yield the same effect each time it's
activated and can therefore be activated over and over again. This is commonly associated with an

HTTP put or delete method on the web. Conversely, a non-idempotent link is one that may have
different effects each time it's activated. On the web, non-idempotent operations are most commonly

associated with HTTP post. The link types in hypermedia controls that you'll select will very based on
the details of your particular system. However, the basic workflow in a hypermedia driven system

should generally look similar to the workflow shown here. All clients begin at a single entry point
resource which returns a representation containing hypermedia controls. The client probably together
with the user will select a hypermedia control based on the controls link relationship type. Remember,

the link relationship is what gives meaning to the control not the URL itself. The client will then activate
the hypermedia control, dereferencing the URL behind the control and initiating whatever state

transition is described by it. In this case, the transition is an HTTP request to create a new child. As you
can see, the control was selected based on the new child relationship type and it's likely that the

hypermedia control directed the client to use HTTP post for the state transfer. Also, note that in
additional hypermedia control was returned in the resource metadata of the response, in this case,

using the HTTP location header.

Summary
To recap, the focus of this module was to identify the actual elements that make up the uniform

interface and show how they relate back to the RESTful constraints identified in module 2, as well as
help address the reasons for REST called out in module 1. With the conclusion of this module, you
should now have all of the background and then some that you need to design RESTful systems. In the

next couple of modules, we'll switch our attention from background and definitions to some practical
tips for designing RESTful systems both services and clients.

Designing RESTful Services


Overview
Starting in this module we're going to shift the focus from talking about the definition and theory of

REST to actually designing a sample RESTful system. This module will focus on designing a RESTful
service while the next module will focus on designing a RESTful client. Also while we won't be showing
much code in either module, the sample that I'll be describing is publicly available. You can find a link

to the project in the references section. This module is broken out into basically two parts. First we'll
introduce a framework for thinking about RESTful design and see how great examples of REST are all

around us in the real world. We'll then introduce a sample bug tracking application and spend the
remainder of the module walking through the process of designing the service.

A New Metaphor
One of the biggest barriers to approaching RESTful design, for me at least, was that regardless of how
well I understood the theory, no matter how many times I read Fielding's dissertation, I still

approached the design problem with all of the mental baggage of architecting object oriented
systems. Even worse, I tended to look at the problem space through the lens of the tools and the

technologies that I was already familiar with. Because I had a background in buildings MBC
applications that used a relational data base as the backing store, guess how I tried to think about

RESTful design? Now I describe this knowledge as baggage and that's not really a great description.
Having a solid background in technology is a really good thing. However, we have to be cognizant of
the fact that it also gives us a lens or a metaphor for how we see the problem space. And

subsequently how we think about design. The danger then of approaching REST with a strong
background in some of the Web technologies I mentioned, is that they bring with them some existing

metaphors. Like for example, classes and methods. And these naturally lean toward an RPC style of
writing services. If we want to build great RESTful services then, we need a new metaphor. Now

fortunately we don't have to look far to find a workable metaphor. In fact, we simply need to look
outside of our closed in technology universe or perhaps back in time a bit and examine how we would

construct systems. And by system I mean any organizational structure if we didn't have computers at
all. How would you construct a system if all you had to work with was paper and something to

organize those piles of paper? Like for example a desk tray. This isn't a very far fetched idea, in fact I
think that if we went around and looked at many smaller businesses we would find that this approach
is still favored for many types of work flows. As a matter of fact we really don't even need to look

outside of the software development world to see a very relevant example of REST. Almost every
development team these days manages some or all of their work flow using a very non-technical

solution. A set of sticky notes and a board divided into columns representing the state of work items.
Let's take a deeper look at this example and see how it can help us better think about RESTful design.

Real-World REST: Bug Tracking


When we consider the process of managing a bug tracking work flow, using the example of our team
bug board, we don't start breaking things down into classes and methods do we? Of course not. We

start by looking at the physical elements that enable the work flow. And in this case there are really
just two main elements. The sticky note and the bug board. Let's start by looking at the sticky note. In
order for the team to work efficiently everyone needs to understand and agree to the format of the

sticky note. As it will serve as one of the key ways that the team communicates internally as well as its
status externally. So let's start with a title and a description. This seems pretty straight forward. It will

help everyone who looks at our bug board know what our bug is as well as get some level of context.
Next let's put the assigned user's initials in the bottom left hand corner of the note. Also because we're

an agile team and we want to promote self assignment, bugs won't be assigned to a team member
until they are going to be actively worked on. So that gives us a basic idea of what our sticky note

should look like. Let's take a look at the other major element of our work flow, the bug board itself. In
our simple example we're going to divide the board into three basic columns. Backlog, working and

done. When a new bug is created it will automatically go into the backlog. When a team member
decides to pick up a bug to work on we'll move the sticky note into the working column and naturally
when a bug is fixed we'll move the note into the done column. Pretty straight forward, right? Now the

work flow that we've defined likely matches many of the work flows that you're used to seeing.
However, from a REST prospective there's one fundamental problem with it. Namely, we're relying on

a shared implicit understanding that the team knows how to move bugs across the board. For
example, how does the team know that new bugs should be placed into the backlog column and not

directly into the working column? To address this potential problem let's add some iconography to
make the next steps more explicit. We'll take advantage of the bottom right corner of the sticky note

and add a few icons that represent our bug states. We'll also add those same icons next to the words
on our bug board. As we complete one state we simply cross it off on our sticky note and then look at

the next icon to see what column to place the note into next. This gives us the ability to do something
pretty cool. We can now completely change the workflow without having to disseminate implicit
knowledge throughout the team. Now this is important because depending on the size of the team,

communicating this kind of knowledge reliably could be all but impossible. In this case we've added a
new bug state called QA. And it sits between working and done on the bug board. After all, it's good

to test your bugs, right? In addition to simply adding a new column on the board, we've also added a
new icon to the sticky note. This means that team members can follow the exact same workflow that

they had previously, cross off the completed state, look to the next icon and put the note into the
column that has the matching icon. This is actually a pretty big deal as it's where a lot of RPC systems

fall over from a maintenance prospective. To make this kind of change in an RPC system you would
have to version and redeploy all of the clients so that they know to call a different method. Or in fact,

even know that that method exists in the first place. In this model our client workflow hasn't changed
at all though the overall system workflow has. Let me reiterate that. In a RESTful design I can change
my system workflow without changing my client workflow. We'll see this in action later in this module

as we design the RESTful bug tracking solution. Now, our solution is looking pretty good, however it
has some issues in the physical world. If I want all of my clients to automatically start moving notes

from working to QA, I would need to modify all of the notes that have already been created and
placed on the board with the new icon. This is where the world of software can actually help a great

deal. Since your client always interacts with resources that are generated by a server, then the server
can dynamically make these kinds of insertions without the client needing to know or care. Hooray for

software.

Designing the Bug Tracking Service


Okay. So we now have a physical world analog for our bug tracking service. Which answers that initial

question, how would you design a workflow if you had no computers? Now let's apply some of the
design principles of our physical world design to our software system design. Like any good software

project we'll start out with a few high level requirements. However, this is where our process may
change a little bit from what you might otherwise do. Because our contract in REST is the uniform
interface, we want to start mapping our requirements to that contract as soon as possible. Therefore

we will identify the possible state transitions for the system, identify the resources that fall out of that
and then design our media type based on the possible state transitions as well as the state elements

from our business domain. Because a RESTful design gives the flexibility to dynamically modify things
without breaking components and of course because this is an example and not a real application, our

requirements are pretty simple. First we want to discover bugs in the various workflow states. We'll
start with our three initial states of backlog, working and done. We'll also see how to dynamically

change this as we did in our physical world example but more on that later. Next we want to be able
to add a new bug. As I described earlier, we want to ensure that new bugs are added in the backlog
state. Finally we want the ability to move bugs through the various states. From backlog to working

and from working to done. Notice that I used some RPC ish language here. I did this deliberately, not
to promote RPC, this is after all, a course on REST but to give you a way to see how an RPC way of

thinking about this domain can translate into a RESTful design. Because we have a simple domain, we
have a pretty simple state transition model. From a starting state we can move through a series of

state transitions all of which put the system into a state that is a collection of bugs. There are a few
important points to note here. First, we've captured two things in this state model. We've captured the

application states such as entry and bugs collection. As you'll see in a few minutes, this becomes
important for helping to design your media type. Second, we've captured the different states that our

bug can go through. We'll use this information in the next step where we identify resources. Another
point is that a client for our service needs to know about only one URL and that is the entry URL. From
this resources representation the user, by way of the client, should be able to discover all of the other

capabilities that the service has to offer. Finally, for the sake of diagram simplicity, we're not showing
navigation and error transitions. Navigation transitions are those transitions available in every

representation that enable a client to get a representation of all bugs in the various bug states,
backlog, working and done. And thereby addressing our first requirement of discovering bugs in

various states. Similarly transitioning to an error state is possible from every other state.

Bug Resources
Based on our previous state model, let's tease out some resources. Because I want to follow the

design of my physical bug board, I'm going to create individual collection resources to identify the
various states that a bug can go through. This is by no means a requirement for my design to be

considered RESTful. I could have arrived at a design where progressing the work flow was
accomplished by manipulating a data element on a bug representation and then updating the state of

an individual bug resource. However, I chose to create different collection resources because it better
mimics our physical world analog and I also think it helps to illustrate the point that resources are
maps to entities that change over time and it keeps us from inadvertently falling into the belief that

REST equals crud over the network. So we've mapped the workflow onto conceptual resources. The
next step is to map those resources onto something a little more concrete. Since we're building this

system on top of http let's map our resources and state transitions. We'll start appropriately with the
entry point resource. The purpose of this resource is really just to serve as a jumping off point for the

other resources with its representations. Think of this resource as being equivalent to the person at the
reception desk who says why yes, the bug board is in room 3224. This resource is only responsible for

handing out representations and therefore supports only the http get method. The backlog resource
or the backlog column on our physical board represents bugs that have not yet been activated. To

support our first requirement, of being able to discover all bugs in the backlog, we want to support the
http get method. Additionally in order to support the requirement that a bug can be moved to the
backlog, we also support posting a bug representation to this collection resource. The working

resource represents bugs that are being actively worked on. The behavior of state transitions here is
the same as it is for the backlog resource. Additionally the server should validate that a bug

transitioning into this state is actually assigned to someone. Finally the done resource represents bugs
that are, well, done. Its transitions are designed in the same way as those of backlog and working. Now

you may be wondering why I chose post rather than put to move bugs between states. The reasoning
has to do with the meaning that is ascribed to each method by http. According to the http

specification, the URI in a post request identifies the resource that will handle the enclosed entity. In
contrast, the URI in a put request identifies the entity enclosed with the request. The user agent knows

what URI is intended and the server must not attempt to apply the request to some other resource. In
my service I'm sending a representation to the collection resource and then modifying the state of a
bug entity with the relevant status, backlog, working or done. Therefore it's important that I use post.
Bug Representation
So at this point we've identified application states and the transitions between them. And we've
mapped those onto the uniform interface elements of resources and self describing messages. Now

let's spend some time focusing on the design of how we will represent our resources. When you're
planning your representation there are quite a few options that you have to choose from. In his book

on Hypermedia API design, Mike Amundsen breaks these options down to four questions. The first
question is around what format you want to base your representation on. The most common formats

used by APIs today are XML and Jason. But this can really be anything. In fact, you can choose to
support multiple based formats. The next question is around what type of state transfer your API will
need to support. For some designs the API may be read-only and in that case the question of state

transfer is not very relevant. In cases where state is transferred to the service however, as is the case
with our bug tracking service, you have the choice between pre-defined and ad hoc. Pre-defined-state

transfer relies on the client having prior knowledge of your format. Typically via your media type
specification so that it can construct a valid representation. Ad hoc on the other hand means that the

server will tell the client in the representation how it needs to go about constructing a valid
representation. A good example of this style is html forms. The next question is around how the

elements of your domain will map onto your base format. As you can see here there are three ways
that you can map the two. In a specific domain style you create domains specific elements and
attributes. For example, with the XML based format you would create a bug element with a title

attribute etc. the general style is bound to a more generic domain. It's not specific to your business but
it's not just a data structure either. A good example of a broadly used domain general media type at

the moment is Adam. Finally, an agnostic domain style is a media type that is completely unrelated to
any specific business domain. A good example of a domain agnostic media type is html. The final

question in representation design, and it is relation to the previous question of domain style, is
application flow. Application flow is defined as the elements that allow a client to recognize and

respond to possible state transitions. To put it another way, this question is around how the
representation format let's a client know that a link exists and what it can do with it. As in the case of

the state transfer question, it is possible that a format will have no application flow identifiers. More
likely however, will be the choice between intrinsic and applied. In the case of intrinsic the media type
will have built in elements for representing length and expressing their semantics. This will be more

common with specific and general domain styles. In the case of applied, the media type does not have
all of the necessary facilities for fully expressing application flow identifiers. However, it gives the

designer the ability to apply attributes to its elements in order to express those concepts. A great
example of applied application flow can be seen in the REL and class attributes within html. So based

on the options that we have, let's look at the choices that we made in designing the bug tracking
service. Because it already has quite a few hypermedia controls I chose html as the base format. This

choice also makes testing the service a little easier as I'll show you in a moment. The state transfer
style will be ad hoc since we're using html forms to provide the state transfer elements to the client.

The client will simply fill in the values and submit the form. Like I said earlier, html is a domain agnostic
format. It's not tied to any specific business domain. This means that we will need to apply our custom
application flow identifiers using an element of html. Fortunately html gives us a bunch of different

options with attributes such as class, REL, ID and name. Based on the application states and
transitions that we identified earlier, we can put together a list of the different elements that we're

going to need to represent our system. Obviously we'll need a list of bugs and structure for identifying
the various data elements of a bug, such as title and description. Additionally for each bug we'll need a

few possible non item potent link templates for moving the bug into various states. Now, the key
benefit of a hypermedia design is that not all of these link controls will exist for every representation.

When a bug is in the backlog state only the link control for moving it to working is presented. When a
bug is in the working state the controls from moving to backlog and moving to done are available. And

this is how a hypermedia driven design enables the client to discover the right thing to do without
having to have prior knowledge or knowing the right procedures to call. In addition to moving a bug
around we also need a hypermedia control for adding a new bug. As we mentioned earlier this will be

equivalent to creating the bug and putting it into the backlog state. However, all this is opaque to the
client. Our service provides an add-bug semantic and the client simply follows the link. And finally all

of our representations should have a set of navigation links so that a client can browse bugs in the
different bug states. These will simply be outbound links. Now as I mentioned a minute ago, html

provides quite a few different options for declaring application flow identifiers. Here is a small sample
of how I'm using different html attributes and elements to map my domain concepts onto html. I find

this approach to be helpful in documenting my representation along with providing a sample of the
representation, which I'll show next. The key thing to remember is that you're capturing all the details

that a client will need to recognize. Remember in REST we don't have service descriptions. The
primary thing that clients will look to for understanding is the documentation around your
representation format and its associated media type. A quick word though, about when to use the

different html attributes, if you choose html as your base format. There's much more detail about this
in Mike's book, but here is a quick summary. ID is used to identify a unique data element or a block

within a representation. For example you'll see that I use it to identify the major state blocks in the bug
tracking representation format. Name is used to identify a state transition element within the

representation. For example an input element. Class is used to identify any non-unique data element or
block within the representation. For example, in the bug tracking representation you can see that I use

class to identify data elements like title for each bug in a list of bugs. REL is used to identify a non-
unique process flow element within the representation. In the bug tracking representation I use REL

with anchor tags to identify the purpose for the link. Note that with both REL and class you can have
multiple values separated by a space and this can be very handy when you want to enable your clients
to slice and dice available transitions rather than always having a one dimensional list. So the table can

provide a lot of good details about your design but it can be a little hard to visualize what an actual
representation will look like. As such, I always find it helpful to include a sample of the representation

as you can see here. There are a couple things I'll point out. First, notice that I've omitted all of the H
ref and action attributes. This is in part to conserve space, but more importantly it's because the actual

link values do not and should not matter to the client. In an example, RESTful interaction the client
decides that it would like to activate the index link based on the REL value. It then simply issues a

request to the value of the associated H ref attribute. It doesn't matter what the value actually looks
like. It could be a pretty URL courtesy of a framework like MBC or it could be their Quids strung

together. In REST the URL is not the important part. Second, notice how I have class values like MOO
space action space next. Remember how I mentioned that you can specify multiple relationship values
separated by a space. This gives the client the ability to, for example, to get and present the user with

all of the move links found in our representation. I'm also using next here as a hint to my clients to
show the optimum path through the workflow. This is by no means a requirement, but it's a helpful

tool that you may find that you want to use.

API
I mentioned earlier that choosing html as my base format brought with it some additional benefits

from a testability perspective. Specifically I'm referring to the fact that because the html media type
has a known user agent, a Web browser, it becomes easy to test your API by simply navigating to the

entry point URL using your Web browser and then simply following links and activating hypermedia
state transition controls.

Dynamically Modifying the Workflow


Now, remember from our real world example, when we introduce the iconography for identifying the
next state in our workflow it meant that we were able to dynamically introduce a new workflow state

without breaking our client. The ability to have this same kind of dynamism in software is in my
opinion, one of the coolest things about having a hypermedia driven API. Let's modify our system

design by bringing in the QA state for our bug workflow. We then need to modify the state transitions
so that a bug flows from working to QA and then from QA to done. Additionally a bug can flow from
QA back to working in the event that during the QA process it's determined that the bug is not

actually fixed. And a bug can transition from done to working in the event that it is reactivated. So
what does this mean for our representation format? And what does it man for clients? On the server it

means that I create new resources as you can see from the circle in green. However because clients

don't actually need to know about URLs this doesn't really have an impact on them. The only thing
that a client really needs to know about are a couple of new link relationship values for both the forms
class and the anchors REL attributes we've added a new link relationship value called QA. Additionally

while a client should understand these, it shouldn't break if it doesn't. We'll talk about that a little bit

more in just a minute. Equally important to adding a new hypermedia control to move the state of a
bug from working to QA is the hypermedia controls that are removed. With my modified

representation a bug in the working state will no longer have a hypermedia control to move it to the

done state. This design only let's the client see the operations that are actually valid for them to do.

Making the distributed system far less brittle. I mentioned a minute ago that a client doesn't actually
have to understand the new QA link relationship type in order to make progress. This is because of

that next hint that I'm using in my link relationship values. Remember that I mentioned I'm adding a

link relationship value of next to the hypermedia control that represents the ideal path through the
workflow. This means that in the example here the client can present to the user the ideal next state

transition and then activate the hypermedia control without even knowing the full meaning of the link

relationship. Now certainly this won't work for more complicated state transitions but it's a pretty cool

illustration of the power of hypermedia. As holds true for most software development projects, getting
version one of a service is usually the easy part. But what about versions two, three and so on? How

do we add new features and fix our own bugs after our service has become immensely popular and

we have thousands of different clients on different platforms using it? In the Web service world this

was a relatively simple question because there was really just one way that versioning was done. And
this was by versioning the service, usually taking the form of a version identifier somewhere in the

URL. Now this strategy makes perfect sense in a world where the unit of versioning is the service or

the service description. In fact, there's not really another option. In REST however, the contract is the
uniform interface and this means that you have quite a few different options for versioning based on

the specific thing that you're versioning. In many cases you can version within your representation

which means that you don't need to do anything from a formal versioning prospective. This is possible

when adding things to your representations definition. Your service adds whatever it wants and clients
should simply ignore what they don't understand. When the semantics of a representation change as

the result of a rename or deletion of an element, you may need to version your representation. In this

case you can take advantage of content negotiation to ensure that your clients are able to specify and

get the representations that they need in order to function. Note that there is not really any
prescription regarding how this representation Meta data should be transferred from the client to the

server. Embedding this information as part of a custom media type name, using a parameter on https

accept header such as version or profile, or using a custom http header, all of these are valid
approaches. Finally if for some reason your server can no longer preserve the semantics of the map

between a resource and its associated entities, you may need to version the resource itself which is

not versioning, so much as it is creating a new resource. But it will manifest in the resources identifier

which in http terms is the URL. So this approach may look most similar to what you've used with Web
services in the past.

Summary
In this module I presented a mental model for thinking about RESTful service design and we spent
some time walking through a sample bug tracking service. We looked at how to extrapolate states and

transitions based on requirements and resources from states. We then took a look at some of the

basics of representation design. For more on that subject I highly recommend Mike Amundsen's book

on designing hypermedia APIs. We finished up by looking at some different strategies for evolving
RESTful services and saw that we have more options then we did back in the Web service days. My

hope is that at this point you're able to think about your own services through the lens of, what if I

didn't have computers? Now that we've looked at RESTful service design, we're going to move over in
the next module and look at some design principles for RESTful clients.

Designing RESTful Clients


Overview
After the last module you hopefully now have an approach that you can try out for designing and
building RESTful services. However, as you've also seen throughout this course, REST is all about
describing the complete network interactions between clients and servers. Since the system made up

of just one component would be a pretty boring system. So in this module we're going to talk about

some strategies for designing and building RESTful clients. Now, the format for this module may feel a

bit looser than in the previous modules. This is because in my opinion the process for designing
RESTful clients is a little bit more open then it is for services. And this is because there is much greater

diversity in the number and types of clients than there are for services. So this module will be

structured into basically three sections. First we'll go through some of the challenges that can make
RESTful clients more difficult to design and build then clients in some other architectural styles. We'll

also revisit the benefits of REST to see why overcoming those challenges might be worth it. Next, I'll

present an approach that you can follow in designing a RESTful client and we'll walk through an

example where we design part of a command line client for the bug tracking service that we designed
in the previous module. Finally we'll look at the key principal to keep in mind when designing a RESTful

client, remembering the contract between client and server. We'll review the constraints that make up

the uniform interface and I'll give some practical examples for how you can use some of the related

data elements in designing your clients.

RESTful Clients Can Be Harder


And while I don't think it ends up being prohibitively so, I think there is a reality to building RESTful

clients can be harder than building service oriented applications in other architectural styles.
Particularly RPC. I believe the primary reason for this is based on the definition of the contract.

Remember that in the RPC world, the contract is generally a service description document. This

document outlines all of the service end points, the operations that they make available, the data types

used to represent the arguments and return values, the possible exceptions that can be raised by an
operation, even different policies that can be applied to services. The key thing is that all of this

information is generally specified in one place as a part of what could be thought of as a self-

contained application protocol definition. In REST on the other hand, the contract between client and
server is the uniform interface itself. this contract is both less restrictive and more restrictive in some of

the aspects that I mentioned above. For example, there are no services and operations in a RESTful

system, only resources and standard control data elements such as http verbs. Also in REST there are

no data types, no arguments, no return values. There are simply media types which again, are a mere
sequence of bytes from the viewpoint of the uniform interface. And a resource can support multiple

media types which can be negotiated between the client and the server. Finally, in REST, hypermedia

driven workflow enable the relationships between clients and servers to be much more dynamic in the

sense that components can be moved around. Resources can be added etc all without breaking
clients. All of this dynamism and looser coupling generally comes at a cost for folks wanting to design

and build RESTful clients. And this is what I really mean when I say that designing RESTful clients can

be harder. The cost is that compared with what's available for RPC architectures, the availability of
tools to perform tasks such as generating proxy objects is not as simple to do for REST. In REST the

network is not something to be abstracted away. And as I hope you're starting to see, this is a good

thing. At the end of the day though, whether or not you should consider a RESTful design, depends on

your particular application needs. Just as a reminder, here is some of the key properties or benefits of
REST. You remember heterogeny, which is seamless inner operability between connectors regardless

of language or platform. With scalability we scope complexity to a uniform interface and a single

communication layer. With evolve ability clients and servers can evolve without making each other or
the entire system unstable. Visibility means that the state of the system can be determined by

examining messages. Having this visibility means that we can develop rich compensation strategies

that can be built against the uniform interface and the self describing messages, making our system

more reliable. For efficiency, local and intermediate caches can take load off of origin servers, enabling
them to handle more clients. Similarly those same local and intermediate caches can improve the

speed of getting a response improving performance. Finally, layering architectural elements enables

the overall system to grow in complexity without impacting an individual layer, making each layer

independently manageable. At a high level you could say that REST is optimized for run time
experience including things like stability, ease of modification etc. And optimizing in this way can have

a negative impact on design time or development time experiences. So one of the first things for you
to determine is whether or not your application should be optimized for run time or for development

time.

Client Design Process


So even though we're talking about client design in this module the key design metaphor is the same

as what we discussed in the previous module on service design. And that is, what would your design

look like if you had no computers? Just paper and some way to organize paper. In the previous
module we looked at elements of this metaphor such as how information should be arranged on the

paper and how we move papers between different buckets as a part of a workflow. RESTful client

design is more analogous to the people in our paper based workflow illustration, who take papers

from one container, do some work on them and put them into another container. It's the space in
between, if you will. Let's revisit our bug workflow from the last module. Remember that our

application simulates a typical bug tracking workflow that uses a dry erase board and sticky notes. In

the last module we spent a large part of time answering questions such as what does the sticky note
look like and what does the board look like? As a reminder you can see both illustrated here. as you

can see, our sticky note has a couple pieces of data for things such as title, description and the initials

of the person to whom the bug is assigned. Additionally we've defined some iconography to both the

sticky note and the bug board. This will provide visual cues to the human in this module, the client, to
know how to move the bug through the workflow on the board. And thereby making the actual

workflow explicit rather than what usually happens which is to have the workflow as implicit

knowledge which is shared by the team. if I'm designing a RESTful client the first obvious question that

I need to know so that I can start designing, is a little bit more fundamental. Where's the board? We're
going to design a client for the bug tracking service that we designed in the previous module and as a

part of that design I'm going to propose a workflow that you can see here. The entry point for client

design is to take a read through the documentation of the media type or the media types being used
to support the service. This will give you a baseline understanding of the media type syntax as well as

an understanding of any additional semantics that the media type supports. For example, does it

support hypermedia and if so what hypermedia controls does it provide. Once you've reviewed the

media type documentation it's equally important that you understand how the service's business
domain has been mapped onto the type. Particularly if the chosen media type is domain general or

domain agnostic. Documentation can be very helpful here but I typically find sample documents to be

more helpful for this part of the workflow. I'll usually start creating my client design based on the

sample documents and use the domain mapping specification for support or for validation. Once you
have a good expectation about what representations will look like the next step is to make a request to

the service entry point resource and get a real representation. As you can see here, I'm using the curl

tool for this. Next, take a look at the response representation and see how well it lines up to what you
were expecting after having looked at the media type specification and sample documents. Assuming

that it looks consistent, if it's possible go ahead and write client functionality that relies on this

resource. Next, based on your inspection of the returned representation take a look at the links that it

contains and based on the client feature that you're trying to implement, follow that link and repeat
the entire process until you've completed your client application. The key point here is that because of

constraints like statelessness and the uniform interface, your client learns arrest API through the

process of discovery rather than needing to understand the entire API at a single point in time.

Example: Bug Tracking Requirement


So let's take a sample requirement from our bug tracking application. We want to be able to discover

bugs in various states. Some examples here are backlog, working, QA and done. So let's walk through

the process and iteratively design our client. In the previous module you may remember that I decided
to use html as my media type because of its support for hypermedia controls as well as its ability to

enable testing the API using a browser. But another benefit to html is that I already know it. and as

such my first step was honestly not to go to the html specification so that I could understand the
media type. Though I did refer to it when looking at attributes like class and REL. However, this may

not always be the case. As an example let's say that I wanted to use a Jason based media type that

also had support for hypermedia. In this case I would likely choose the Hal Jason format. Because I'm
not intimately familiar with Hal the first place to start would be at the media type specification shown
here. if you want to learn more about Hal make sure to look at the references associated with this

module. By looking at the specification I can determine the general structure for organizing data as

well as how links and link semantics are to be formatted. Because html is a domain agnostic media

type I also need to look at something to tell me how my business domain, bugs in this case, is mapped
onto an html representation. There are two primary ways that I can acquire this information. From a

mapping specification and from sample documents. Like I mentioned a minute ago I generally use the

sample documents as a starting point and refer back to the specification as necessary. Either to

validate my understanding of the sample document or to clarify when the sample documents seem
ambiguous. However, where you decide to start is really more a matter of what works best for you.

And more importantly what is available to you. From example some service authors may publish only

one type of reference or another. We now have an idea of what a representation should look like. So
let's issue a request to get a representation for the services entry point resource. Again, I'm using curl

for this task because it's very lightweight. Just in case you're curious the H parameter tells curl that I

want to specify an http header. In this case I'm specifying some representation Meta data, the except

header, so that I can ensure that the server knows that I want html in the return representation. Issuing
the curl request gives me the following html representation. As you can see, this is completely valid

html and I've mapped my bug tracking domain onto it using attributes such as ID, class and REL. The

document is divided into three sections, bugs, forms and links which is expected based on the sample

document and the mapping specification. Also you can see that even in this entry point representation
there are quite a few things I can do. the most notable being that I can add a new bug. However,

remember the requirements that we're trying to design at the moment. We want to enable a user to

discover bugs in various states. As such, the only section that we're interested in right now is the links
block at the bottom. In this block you can see that there are quite a few anchor elements with link

relationships that identify the various states that a bug could be in. So let's start there.

Bug Client Code


Now I know I said at the very beginning of the course that we wouldn't be looking at any code and for

the most part that's true. But this approach to design involves getting your hands dirty as quickly as

possible so you will have to forgive me because we will be looking at some code here. Our client in this

module is a simple console application written in C Sharp. However, the code is simple enough that I
expect you can translate it into your language of choice without any issue. Based on our requirement

of enabling a user to discover bugs in various states and based on what I can see from our entry point

representation, there are three basic pieces of functionality that we need to write for our client. We

need to be able to display links to all of the various bug state collection resources. We also need to
enable the user to activate one of these choices and get the collection of bugs in that state. Finally, we

need to be able to display a list of bugs to the user. The code for displaying the list of bugs looks very

much like the code shown here for displaying the list of links. So I'm not going to show it here in this
module though the entire sample application is available online. See the references section for more

on that. However, as you can see here I've parsed my html response into an xml document and

displaying the list of links involves issuing a standard X path query based on a known ID attribute

value. The key thing here is that the client doesn't need to understand the entire document by way of
some kind of serialization mechanism. It cares about just one thing. Being able to write out a list of

navigation links. After showing the user a list of possible links that he or she can use to discover bugs

in various states, the next thing that we need to do is enable the user to actually choose a list of bugs

to see and then go fetch that list. just like we did in the previous example we find the appropriate
element by way of our X path query. In this case we're relying on two bits of domain mapping

information that was specified out of band by our domain mapping specification. The state block

identifier which shows up as the ID of the div and the link relationship type on the anchor tag.
Assuming that the user has entered a valid link relationship identifier in the link command value, this

code then simply extracts the value of the H rep attribute and D references the URL to get a new

representation. Now, one thing I want to call attention to here, you may be saying to yourself, wow,

that X path looks really ugly. Is REST really this much of a step backwards? One of the realizations that
I came to, particularly as I was implementing this sample, is that while media types like html are great

in this sense, that the media type specification defines a rich set of hypermedia controls. Those
controls are not all that helpful if you don't have a user agent or a library that can actually work

intelligently with the media type. For example, when surfing my API the browser gives a complete html

document object model or dom to work with. However, in my console application I don't have this kind
of object model. And so I'm having to work with a semantically rich media type format as if it were a

much less meaningful xml document. I bring this up because as you're evaluation what media types

you want to support in your RESTful design, it's important to consider what types of clients you think

you will need to support and pick a media type based, in part at least, on what kind of library support
exists for that media type. So we examine the relevant specifications and sample documents, issued a

request to the entry point resource, received a representation and even wrote client code to display a

list of links representing collections of bugs in various states and letting the user follow one of those

links. The next step is to iterate through that loop again by following one of those links ourselves. As
you can see here I'm simply picking one of those links and using Curl again to follow it. I can then

continue to iterate on my client in this way until I've implemented all of the desired client functionality.

Remember the Contract


Now while I hope that the workflow I've presented works for you in designing your RESTful clients, the

reality is that people are different and so different approaches work better for some than others. In

fact, I'll be shocked if I still use the same workflow in a year or two since, just like you I'm always
growing and improving the way that I do things. More important than the design approach though, is

this. However you approach designing RESTful clients you need to remember the contract and again,

in REST this is the uniform interface. And it consists of four things. Identification of resources,

manipulation through representations, self descriptive messages and hypermedia as the engine of
application state.

Clients and Resources


While the identification of resources is generally more of a server design activity, a client should be
aware of the different types of resources that are available so that you as the client designer can

decide what you're interested in when inspecting a representation. More importantly, knowing the

available set of resources will help you make better sense of link relationships when you encounter

them. past that, you don't really want your client to care all that much about the details of resources,
and particularly resource identifiers, as this can lead to undue coupling between clients and servers.

While your client shouldn't need to know that much about resources themselves the resources Meta

data that servers may provide can prove very helpful in optimizing the communication between client
and server. For example. Consider the following http exchange. This exchange takes advantage of

some control data along with a very helpful piece of resources Meta data. The entity tag or e tag. This

Meta data is passed to the client in a response header and can be used but the client to make what's

known as a conditional request. We talked briefly about conditional requests back in module three.
Now, most people identify conditional requests with conditional get requests as a way to optimize for

caching scenarios. However, as you can see here, they are also helpful for ensuring that put of post

operations don't end up overriding resources that shouldn't be overridden. In this exchange two clients

are trying to update a resource. I omitted showing client two getting the resource for brevity sake.
However, the important thing to note is that when client two updates the resource the value of the e

tag changes. when client one then tries to update the same resource, it issues the update request with

the if match header containing the e tag value that represents that last state it had for resource one.
This conditional header is equivalent to saying update resource one if the current state of the resource

matches the value that I'm presenting here. Because the state of resource one has changed as a result

of client two's update, the update cannot progress and the server returns a failure status code.

Because the client is aware of control data such as status codes, and we'll talk more on that later, it
can intelligently react by getting the most recent representation of resource one. This response will

contain an updated e tag value of two. The client can then ask the user to do some conflict resolution

if appropriate and then issue the same conditional update request with the new e tag value. Assuming

that the state of the resource has not been changed by another client during the conflict resolution
process, the update will succeed and a new e tag value will be included in the resource Meta data of

that response.
Clients and Representations
As we've talked about in past modules a representation is how a client actually interacts with a

resource. And multiple representations can be supported by a server. From the client design

perspective the key principal is to not make any assumptions about what representations a server will
return for a resource. Instead you should rely on representation Meta data both in requesting a specific

representation from a server and in processing the specific representation returned. Also unlike in RPC

representations are not simply serialized data types. As such, they may, over time, have items added to
them that are not relevant to your client. However, just because a bit of data in a representation isn't

relevant to your client it certainly shouldn't break your client either. Finally, as we talked about in the

last module, if you need to change your system in a way that changes your representation format, you

can take advantage of https content negotiation ability to perform your versioning. Let's do a quick
demonstration of versioning a media type using content negotiation. Here you can see a bug's

representation that should look pretty familiar. The thing that's different is that we've changed the

value of the except header from text html to a custom media type. Also note that the media type

name include a version number. On the response side my client can look at the content type header to
see what is contained in the response body. It can use this information to process the response body

using the appropriate processor or it can take some other action if it doesn't have a valid processor for

the value specified in the content type header. Again, the key thing is that the client makes a decision
about how to process the content based on the representation Metadata and not the representation

content. Now let's assume that as a part of evolving my service I need to rename some link

relationships. This is not a very desirable thing to have to do but it happens from time to time. So for

the purpose of this illustration that's the data we're going to change. This change doesn't
fundamentally change the meaning of the mapping between a resource and its entities so we don't

need to mint a new resource. However it does change the meaning of elements within a

representation. And so we need to version the media type. In the example here we include a version
moniker in the actual media type name. Therefore all the server needs to do is to start supporting the

version two format. At their own pace clients can start evolving to support the new format by

requesting it in the accept header. Clients that evolve more slowly can continue to request the version

one format. Now, particularly with regard to http know that you don't have to create a custom media
type definition in order to use content negotiation to support representation versioning. Http provides

several different options here from media type parameters to custom headers. You can perform

content negotiation on any of these. The key is that you use content negotiation to version your

representation formats.

Clients and Self-Describing Messages


We've seen tons of examples throughout this course where we've based decisions, both for the server

and the client on Metadata. Whether it was resource Metadata, representation Metadata, or control
data. this is really the essence of self descriptive messages. The more your clients understand all of

these various available message information bits, the more intelligently they can deal with many of the

challenges outlined in module two. Such as shifting network topology or unreliable network or server

infrastructure. In fact, let's look at a quick example of that latter challenge. Sometimes strange
intermittent errors happen on the server or anywhere in between the server and client. Typically when

you build a client using an RPC framework any kind of transient failure causes an exception to be

thrown in the client and many times this leaves the client and the user in a state of being stuck. Http
actually has a status code that can be used to indicate this type of temporary failure. As you can see

here the client attempts to get a resource but can't because of some temporary outage. As a result

the server returns a 503 status code with some control data instructing the client to retry the request

after 30 seconds. If the client is designed to understand these semantics it can simply wait for the
specified time and hopefully achieve success on the following request. The user may have to wait a

little longer but a wait is always better than a failure.

Clients and Hypermedia


Like I've mentioned in the last couple of modules, I'm a big believer in the hypermedia constraint. Your

client should be designed firstly as hypermedia consumers. As I've been demonstrating throughout the
module, your clients should only need to know about an entry point resource. And that resource

should provide the link or links that enables your client to get to all of the different capabilities of your

service. as an optimization your client may hang onto specific URLs and action known as bookmarking
so that it can jump to different parts of your application. However, know that these can possibly shift

so your client should always be prepared to deal with a 404 status code and go back to the entry

point if necessary. Secondly the client should treat URLs in a representation's hypermedia controls as

nothing more than opaque strings. The client should not try and interpret any kind of meaning from
them, rather, the client should look for the meaning of a link from its associated link relationship value.

For example, remember earlier in this module my anchor tag had an H ref value of bugs, slash, backlog

and a REL value of backlog. My client should only care about the REL value. In fact, should I want to, I

should be able to change the H rep value to a guid and still not break my client. And just so you don't
think that this is me being dogmatic, I wanted to show you this quote and this is directly from Roy

Fielding the guy who created REST. Now, and remember that back in module three we talked about all

of the different types of links. Hypermedia controls can include everything from the standard anchor
tag which falls into the outgoing link category here to templated, to item potent and non item potent.

Link relations are specified either as a part of the hypermedia control's definition as is the case with

the html anchor tags REL attribute or you can apply link relationships using a more neutral mechanism

such as htlm class attribute. In my example this is how I chose to identify link relationships for html
form elements since those elements don't have a REL attribute. So take a look at this mark up. Here

we're using html's form hypermedia control, to update the state of a resource. We're specifying two

different link relationship types, new and backlog. The html specification gives us this capability by

declaring the multiple values can be held by a class attribute so long as they are separated by a space.
The action attribute represents the target of the hypermedia control or the address that will be de-

referenced by activating the control. the method attribute tells the client what http method to use

when translating this state transfer block into a new request. Additionally you can specify what media
type you want to use for the representation that will be sent to the server. However, the html

specification defines form URL encoded as the default encoding type. And that's what I would have

chosen anyway so there was no need to explicitly call it out. After the form definition you can see that

the representation includes a few different input elements. A client can simply examine these
elements, fill in the appropriate values and then translate the entire form into a new http request and

representation in order to update the state of the resource, identified by the value of the form action

attribute. And as you can see, when activated the client turned the form into a new http post request

containing a representation of the media type or murl encoded. Additionally the input elements were
converted into a series of name value pairs to form the form URL encoded payload.

Summary
So to recap. In this module we've talked through some of the challenges to building RESTful clients.
We then looked at one approach to designing RESTful clients that enables the design to evolve rather

than having to address every challenge at once. We then stepped back and looked at various aspects

of the key principal to keep in mind when designing clients. The contract or in our case the uniform
interface. At this point we've covered all of the background and design aspects of building RESTful

systems. Both servers and clients. In the next module we're going to look a little more to the future

and see how REST can help in building applications for the Cloud.

REST and the Cloud


Overview
In this last module, we're going to take a look at the cloud and make the case for REST as integral part

of cloud-based architecture. This will be a shorter module than the others as the purpose here is a bit

different. Previous modules were intended more to explain concepts or provide design guidance for
restful systems. This module, by contrast, will attempt to make some connections between what

you've hopefully learned about REST and the emerging world of cloud computing. In examining REST

in the context of cloud computing, we'll start out by taking a looking at some of the goals of the cloud
or at the very least, some of the advertised benefits of moving to the cloud. We'll then look at some of

the architectural challenges that are inherent in building cloud applications, and we'll see how many of
these challenges are really just real-world examples of many of the fallacies of distributed computing

that we talked about back in module two. As we go through many of these, my hope is that you will

already be making the connections between the properties that REST yields and how those properties
address many of the challenges that are inherent in creating a good cloud-based architecture.

Regardless, we'll then lineup the characteristics of a good cloud architecture with the RESTful

constraints that help to create those characteristics. We'll conclude this module with a little envisioning

exercise. I'll tell you about some of the opportunities I've been exploring for optimizing cloud-based
applications by taking advantage of the RESTful constraints and I'll close with a challenge for you to

do the same. I'll then spend just a couple of minutes reviewing all that we've gone over in this course,

as we've covered quite a bit of ground.

The Goal of Moving to the Cloud


At the end of the day, the motivator for a business to do anything, including move its application

portfolio to the cloud, is to increase its profit. Note here that I didn't put this in terms of cutting costs,

it's very possible that when a business moves its applications to the cloud it ends-up spending more
money on IT, but it does this because it can deliver more services faster, and thus make more revenue,

which compared with the expenses spent on cloud resources still yields a higher profit. You may

remember a quote that I used earlier during this course, that in order to get the benefits of a scalable
infrastructure we have to have a scalable architecture that can take advantage of that infrastructure.

One thing that I don't think is called out explicitly though is cost. If you look at the statement narrowly

enough, you might react by saying, well, I can absolutely scale my current application using the cloud.

And I would agree, though I would ask, can you do it cheaply enough to make it worthwhile? Many
architectural styles have their cost inefficiencies hidden by the fact that they run on computing

resources that are owned by a company. Those computing resources are known as capital

expenditures. When a company moves its applications to the cloud, they shift from owning the

computing resources to leasing them, in other words, from capital expenditure, to something called
operational expenditure. And because of the economics behind how many companies function, this

move can be looked on kind of unfavorably by the executives who pay the bills. This means that your

application architecture needs to take advantage of the scalable infrastructure of the cloud in a way
that keeps operational costs to a minimum. To build cloud applications only thinking in terms of infinite

computing resources, is like going shopping with a credit card and thinking only in terms of infinite

purchasing ability. Neither case works out very well.

Characteristics of a Good Cloud Architecture


So then, let's start out by looking at some of the characteristics that form a good architecture for the

cloud. First, such an architecture should be able to scale in such a manner that an increasing resources,

provides a proportional increase in performance. We'll talk more about this in a moment, but I'm really
referring to scalability here. Next, a good cloud-based architecture should be operationally efficient.

Both in how it uses the infrastructure resources that it's built on, and how it can be administered and

managed by human operators. Next, a good cloud architecture should be resilient to failures at all

levels. This includes hardware failures, application software failures, network failures and everything in
between. The application should be able to take advantage of the clouds supporting services to

selfheal as well as ensure that all of the appropriate individuals are made aware of the failure so that

the problem can be corrected. Finally, a good cloud architecture is all about realizing economies of
scale. We'll talk more about this in a few minutes, but the idea is that as the application scales, it

actually costs less.

Scalability
It's hard to think about cloud computing without thinking of scalability. One of the most frequent ways

that I've heard people try to sell the cloud is by invoking the Slashdot effect. If you've never heard this

term used before, it describes the expediential spike in traffic to a website when it gets mentioned on
the popular geek discussion sight Slashdot. In the Microsoft developer world, this is probably more

analogous to getting mentioned by Scott Guthrie or Scott Hanselman. At any rate, let's breakdown

some of the specific challenges related to scaling. First, scaling has traditionally been a bit more art

and luck than science. This is because underlying the decision of when and how to scale is an
assumption that you can predict demand on your application at regular time intervals, for example at

the start of a budget cycle. The problem is that load is in a constant state of flux and so depending on

how budgets are structured, companies are nearly always vacillating between having too much
capacity and not having enough capacity. The reality is that it's unreasonable to regularly predict load.

We need a better way to provision resources. Second, different component types and different layers

have different scale requirements. And like everything else, these requirements change over time. The

key design principle to remember here is that each layer should be responsible for managing its own
scale requirements. You should design your architecture in such a way that a change in resource

scaling in one layer does not cascade down into other layers. Thirdly, scalability is made a great deal

simpler when none of the components involved in processing a workflow are aware of one another.

Typically, this kind of design is enabled via a mechanism like a queue which is used to broker
communication between layers. This is certainly valuable from a resiliency standpoint, but it can also

have some profound effects on scaling. For example, in the event that a queue reaches a certain size,

the layer using the queue as input can scale up its resources to relieve pressure on the queue without
directly impacting any of the layers with which it interacts. Decoupling in this way also makes it much

simpler to implement parallelism across parts of the architecture. Finally, for scaling to be most

efficient, it should be as dynamic as possible. As I've described in that previous scenario of relieving

pressure on a queue, and in order for scaling to be dynamic, the provisioning of new resources must
be automated using technologies like scripting.

Operational Efficiency
Now for operational efficiency, this first point that you can see ties into the automated scaling
characteristic that we just looked at. It just looks at automation from a slightly different angle. What

we're saying here is that for a cloud-based application to be efficient with respect to how it's managed

tasks that were once manual tasks, performed by a network administrator should be automated into

scripts. This means that rather than bringing a new machine online, one at a time, a network
administrator can bring entire clusters online to support a new test initiative or handle a spike in

demand on a part of the system. It also lays the foundation for enabling the system to be more

responsive in recovering from a failure, which we'll talk about next. The second point here is that a
cloud-based architecture should spread the cost of running the system around the entire network of

components that make up the architecture. This means letting go of some expectations around the

needed power of an individual component and instead, architecting for the entire environment. One

example that's used in an Amazon.com white paper on cloud architecture best practices, states that a
server may not have as much RAM as you think you need, but you may have access to a distributed

cache service such as memcached. As you may already be thinking, in REST we can go a great deal

further then distributed server caching, as we want caching to take advantage of the entire network

path from the client all the way to the origin server.

Resiliency
As the quote here says, good cloud architectures should be impervious to reboots and re-launches.

One of the biggest enemies to this capability is having state such as Session State or user context
that's stored in-memory by your application components. Additionally, cloud-based architectures

should be easily monitored either by tools supplied by the cloud provider or by any number of open-

source or commercial tools. These tools can have visibility into the application components, ideally via
their inputs and outputs and they can take action based on administrator configurable triggers.

Actions could be anything from recycling a machine; to restarting a process, to bringing new machines

on line and putting them into rotation on a virtual load balancer. Finally a good cloud architecture

should spread the risk around. At a most basic level, this means to have redundant resources for
application components, however, more practically, it means that you should have components diploid

into different data centers and ideally, even across different cloud providers. No matter how good their
engineering is, each of the major cloud providers has suffered major outages over the last couple

years. As such, you can't assume that your cloud host will be 100% reliable.

Realize Economies of Scale


Now let's talk about economies of scale. The basic definition here is that the cost per unit goes down

as the number of units goes up. So the questions that we really need to address when it comes to a
cloud computing architecture are, how do we measure cost and how do we measure the number of

units? We can measure cost pretty simply as the actual monetary cost of running our application. This

includes the cost of hardware, software, facilities, utilities, etcetera, if you own and manage your own

data center. Or, it includes the cost of service by your cloud provider if you're hosted on the cloud. In
my opinion, this also includes the human cost of developing, enhancing, and maintaining the

application, since I think that there's many times a hidden cost here that ends up growing significantly

over time. The number of units can be measured by the amount of demand or load on the application.
There's more than one metric that can be used to measure this, but I tend to start out using requests

per second. Therefore, by these definitions, my application has economies of scale if the cost of

processing a single request per second goes down as my total number of requests per second goes

up.

REST as a Means to Scalable Architecture


Hopefully as we've been going through some of these characteristics, you've been having thoughts

like, oh yeah, that should be achievable with the RESTful constraint X. What you can see here is a table
showing a basic mapping of the characteristics we just talked about to the RESTful constraints that

enable an architecture to exhibit those characteristics. For example, for scalability, applying the

stateless constraints, enables state to be maintained on the clients, keeping the server from needing to

maintain in-memory stores for user context. The visibility also enables intelligent intermediaries to
automatically provision new resources based on the run-time characteristics of the system. The cache

constraint helps to keep load off of the origin servers, enabling them to handle more load. And the

layered system constraint enables different component layers to scale as they need to, but,
independently of one another. All of the other characteristics of a scalable architecture are achieved in

much the same way, by applying the RESTful constraints. The visibility achieved through the stateless

constraint creates a number of opportunities for intermediaries to optimize component interactions

and recover from failures. The uniform interface enables components to be added, removed, or
replaced at will, without requiring anything of the components communicating with them. The layered

system constraint enables dynamic adding and removing of resources in a way that is transparent to

components in other processing layers. A classic example here is adding a new computing node or a

thousand behind a load balancer; a component that as a client of this layer knows only of the layer,
and not of the individual components within it.

Cloud Architectural Strategies


In that same Amazon.com white paper that I referenced earlier, the author identifies six strategies to
use in designing architectures that will run well in the cloud. The first is to design for failure. Included in

this strategy are infrastructural tactics such as having an automated backup and restore strategy,

implementation tactics, such as building your application to automatically start when a system is
booted and architectural tactics such as avoiding in-memory sessions or stateful user context. As

we've discussed, a RESTful architecture does a great job at meeting this last tactic as a result of

applying the stateless constraint. Next is to decouple your components from one another. The article

describes this in terms of using queues. From a REST perspective, however, the architectural
constraints of the uniform interface and the layered architecture go a long way toward enabling new

layers such as queuing layers, to be introduced over time as the system evolves and as it warrants the

cost of the additional layer. From the architectural perspective, implementing elasticity is all about

ensuring that the cost of automating scale-up and scale-down is as small as possible, making it much
easier to do and in a more granular level. For example, within an architectural layer the RESTful

constraints of statelessness and layered architecture can go a long way to help here. Once we've
decoupled components and enabled the infrastructure to scale elastically, the opportunities for parallel

processing become much more apparent. In addition to the RESTful constraints of statelessness and

layered architecture, the uniform interface constraint and more specifically, self-describing messages

can help parallel controllers to more easily manage these more complicated workflows. The strategy
of keeping dynamic data closer to the compute components while keeping static data closer to the

end-user, in many ways seems like simply another way of restating REST cache constraint. And finally,

implementing security at every level is really something that's orthogonal to REST; however, RESTful
constraints such as statelessness, the uniform interface, and layered architecture create a solid

foundation to enable security policies at multiple levels throughout the overall system architecture.

Cloud Opportunities
With all of this in mind, I want to take this last slide to tell you about some of the research interests

that I have with regard to optimizing a cloud-based architecture using the RESTful constraints and

hopefully inspire you to think of some optimizations that go even much farther. The first is the idea of

cloud-overflow or failover. In the first case a client begins a workflow by consuming services diploid on
premise, however, as the load on those resources grows; eventually a threshold is reached where the

on-premise services need to start directing traffic to the same service hosted in the cloud. The case of

failover deals with how components need to behave when a service provider has a catastrophic failure.

This could be failing over from your company's datacenter to the cloud or more interesting to me,
anyway, you could failover from one cloud provider to another. The way to go about this is to take

advantage of two RESTful constraints. Statelessness and the uniform interface, specifically,

hypermedia as the engine of applications state. The second category of optimizations involves the
creation of different connectors that can be used to auto-tune a service. A few examples, as you can

see here, include the automatic creation and management of entity tags or etags based purely on

resource identifiers and control data such as the HGDP methods. Second is managing cache control

values based on the volume and type of requests that a server receives for a given resource. Finally, as
a representation in-lining which means watching for usage patterns in a resource hierarchy and

automatically expanding links that happen to be followed frequently. Clients can then be built to follow

a collapsed link or they can use an in-line representation directly. Again, these are just a few ideas that

I'm working on that are enabled as a result of the REST constraints and I'm sure that there are many
more. I would love to know what you come up with as you think more deeply about how you can

apply REST constraints in your own designs.

Summary
In this module, we've covered at a very high-level, some goals of the cloud and how those goals must

be realized, not just with a scalable cloud infrastructure, but also with a scalable cloud architecture to

take advantage of that infrastructure. We then delved into some of the characteristics that make up a

good cloud architecture, and described some strategies for achieving it. We also looked back at the
RESTful constraints and mapped them on to the desired characteristics for a cloud architecture.

Finally, we looked at some opportunities to further optimize and add value to cloud applications. My

hope is that this module has started the wheels turning in your head, of all the new ways that you can
apply REST in the cloud to deliver new levels of value. And with that, we're at the end of the course. As

a final quick recap, we started out by setting the stage and establishing why REST matters in a

modern distributed application. We then took a look at the definition of REST and then an even deeper

look as we dove into the individual constraints and data elements. We then discussed the principals
and design strategies for implementing both RESTful services and RESTful clients. And finally, this

module makes the case that REST is an architectural style that is a natural fit for cloud-based

computing. I sincerely hope that this course has been both interesting and helpful and feel free to
email or message me on Twitter with any feedback or additional thoughts. I'd love to hear it.

You might also like