For more information:
Archives
Posts filed under "REST"
| Http Method | RestTemplate Method |
| DELETE | delete(String, Object...) |
| GET | getForObject(String, Class, Object...) |
| HEAD | headForHeaders(String, Object...) |
| OPTIONS | optionsForAllow(String, Object...) |
| POST | postForLocation(String, Object, Object...) |
| PUT | put(String, Object, Object...) |
The method names indicate the HTTP method that they will invoke and the second part of the name indicates what the method will return. The first argument of each method is the URI. The URI can either be a URI template or a normal URI. I am going to show you how to use the RestTemplate to access the dictionary service that was introduced in a previous blog .
GET
To retrieve all the words out of the dictionary we use the following code:
To retrieve a word:RestTemplate template = new RestTemplate();WordList wordList = template.getForObject(" http://localhost:8080/SpringDictionaryService/bti/dictionary", WordList.class);
Map vars = new HashMap(); vars.put("word", "set");
Word word = template.getForObject(
"http://localhost:8080/SpringDictionaryService/bti/dictionary/{word}",
Word.class, vars);
This method uses a URI template and takes a Map which contains the URI path variables. This same example can be done using a normal URI:
RestTemplate template = new RestTemplate();
Word word = template.getForObject(
"http://localhost:8080/SpringDictionaryService/bti/dictionary/set",
Word.class);
POST
To add a new word to our dictionary we use the following code:
Word newWord = new Word("BTIer", "A great teammate"); URI resourceLocation = template.postForLocation( "http://localhost:8080/SpringDictionaryService/bti/dictionary/", newWord);
The above code will add the word "BTIer" to the dictionary with the definition of "A great teammate". The postForLocation method returns a URI which gives the location of the newly created resource. The URI for this newly added word is "/SpringDictionaryService/bti/dictionary/BTIer".
PUT
To update a word in our dictionary we use the following code:
Word newWord = new Word("BTIer", "The ultimate teammate");
template.put(
"http://localhost:8080/SpringDictionaryService/bti/dictionary/BTIer",
newWord);
DELETE
To remove a word from our dictionary we use the following code:
As you can see Spring provides an easy way to create clients to access RESTful services using the RestTemplate. With the ability to also create RESTful services easily, Spring is a great framework for both implementing and consuming RESTful services.
template.delete("http://localhost:8080/SpringDictionaryService/bti/dictionary/BTIer");
ActiveResource can take RESTful resources and map them to client-side classes with almost no configuration or code required by the application developer. Lets take a look at the classic “Person” service example:
class Person < ActiveResource::Base
self.site = “http://www.bti360.com/person-service”
end
In these few lines of code we’ve created a Person model class that can be used throughout our application much like our ActiveRecord based model classes that interact with our database. What can we do with this class? Well, out of the box you can do all the standard CRUD operations.
Lets take a look at how some of these operations might look.
So say we want to create a new person. Here is some sample code to do just that:
jp = Person.new(:first_name => 'Jon’, :last_name => ‘Pierce’)
jp.save # sends POST /people/ (create)
The save method above will send the following XML to the service in the POST request body:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<first-name>Jon</first-name>
<last-name>Pierce</last-name>
</person>
And any response body from the request will be parsed and assumed to be the saved representation of the new person. Once the person has been saved we can easily make updates:
jp.new? # => false
jp.last_name = ‘Awesome’
jp.save # sends PUT /people/1 (update)
So we’re following standard convention here to get us moving very quickly. Similarly we could delete our new person:
jp.destroy # sends DELETE /people/1 (delete)
And now JP is gone.
The final piece to the CRUD puzzle is the ‘find’ method. As with the others, this method behaves similarly to the ActiveRecord find method. Here are some examples:
Person.find(1)
# => GET /people/1.xml
Person.find(:all)
# => GET /people.xml
Person.find(:all, :params => { :last_name => "Smith" })
# => GET /people.xml?last_name=Smith
As you can see ActiveResource provides a lot of power into very little code for the application developer, and this blog has only scratched the surface. ActiveResource has many more options and features to allow you to taylor it to your specific needs and purposes, including validation, error handling and many others.
I would recommend diving into the ActiveResource API documentation on the RoR homepage if you’re interested in learning more about it. Or feel free to shoot me an email, I’d love to discuss it with you.
Happy coding!!!
In this blog we are going to take a look at clients of RESTful Web Services. RESTful Web Service clients are programs or libraries that can be used to consume RESTful Web Services. These clients are responsible for making the underlying HTTP requests to a RESTful Web Service. Every modern programming language has one or more libraries for making HTTP requests and each client will usually use one of these libraries.
To build a RESTful Web Service client you will need an HTTP library with at least these features:
- Supports GET, POST, PUT, and DELETE requests: These four http methods are required when creating and modifying resources.
- Supports adding and modifying request headers: Specific request header values need to be used to specify the representation of the resource (json, xml, jpg, etc).
- Allows the programmer to customize the data sent as the entity-body of a PUT or POST request: This means that the programmer can include any data they want in any representation they choose as the body of the request.
- Allows the programmer access to the response code and headers: The programmer needs access to the response code to determine if the request was processed successfully or if any error conditions exist. Access to the header is used to determine the representation of the resource in the response body.
- Supports HTTPS and SSL certificate validation: This ties in with security as many RESTful Web Services and http servers in general will require the client to support secure communication.
Example Libraries
Some example libraries that support these features are as follows:
- Java: Spring's Rest Template, Apache HttpClient
- Ruby: ActiveResource
- Javascript: Many solutions (XMLHttpRequest, ExtJs, jQuery, Dojo, Prototype, etc)
- C++: Curl
- .NET: HttpWebRequest and HttpWebResponse
Once you have an acceptable HTTP library, you will need another library or piece of code to convert your resource into the chosen representation and vice-versa. The most common representations currently used in RESTful Web Services are XML and JSON.
In our next blog post we will take a closer look at some of the libraries programmers use in their RESTful Web Service clients and dig into some examples.
Its a great video from the smart guys on the Google Data APIs Team. Check it out if you're new to REST and want to get a quick introduction.
In the last two posts we looked at the request and response formats and error handling for REST and SOAP. In this final blog of REST vs. SOAP we want to take a look at a few other important areas that are crucial in choosing one philosophy over the other. After reading this post you should have enough information to decide whether REST or SOAP is right for your current and future web services.
Support/Community
REST is still young compared to SOAP, resulting in less tools and support. Although REST is young, it is growing fast and there are still many frameworks and tools that support REST. Many new web services coming out are RESTful, but SOAP and REST are both currently used by many leading companies offering web services. Companies like Amazon and ebay use SOAP. Google, Yahoo, Amazon, and ebay use REST. It is interesting to note, that Google has discontinued their search SOAP API. Some companies provide both SOAP and REST APIs for their web services, like Amazon. However, given the choice of using the SOAP or REST API, 85% of the requests made to Amazon are through their REST APIAnother aspect of this is the fact that RESTful web services rely almost entirely on the features of HTTP. HTTP is the protocol of the web, and as such it has a lot of support, frameworks, and tools.
Performance
The use of a verbose XML format and a required SOAP envelope for each request and response results in larger messages and more bandwidth when using SOAP. Also there is more overhead in constructing request and reading responses when using SOAP. Shorter request and responses make REST a great option for developing web services where bandwidth is an important factor, such as mobile devices. REST has better performance. According to Amazon, querying Amazon using REST is six times faster than using SOAP. REST supports caching because it makes use of GET requests, which gives better performance and allows for scalability. SOAP on the other hand uses only POST, which means it cannot cache information on the server side.Security
Almost all web services desire some level of security beyond simply anonymous HTTP requests. Both SOAP and RESTful services have robust security options.SOAP has the WS-Security extension from the WS-* family of extensions. WS-Security can provide authentication and encryption, and allows for a lot of flexibility in the algorithms/technologies that you can use for each. The biggest problem with WS-Security is performance. It has been found to be significantly slower than Transport Layer Security (TLS) and Secure Socket Layer (SSL).
Both SOAP and RESTful services can easily take advantage of SSL/TLS. Anytime you send a request over HTTPS you're doing just that. The standard one-way SSL/TLS can be used to encrypt your communications and authenticate the server. This is the most common form of security on the web. However, almost all services will also require client authentication, which is lacking from standard SSL/TLS. It is possible to do two way authentication with SSL/TLS, however it typically isn't practical because every client has to have a certificate signed by a trusted authority.
So how does a RESTful web service authenticate clients. Well, there are a lot of home grown methods, but the fast growing standard is OAuth. OAuth is an open standard that allows services to share private resources. OAuth allows services to hand out tokens instead of usernames and passwords to their resources. Each token grants access to a specific site, for specific resources (e.g. just videos from a specific album) and for a defined duration (e.g. the next 2 hours). Almost all major service providers are either using or moving towards OAuth.
Clients
It's easier to build a SOAP client. There are many tools and IDEs that automatically generate a client to consume a SOAP web service using the supplied WSDL. With REST there isn't an easy way to generate a client, but there are new efforts under way to make it easier to generate REST clients, which will be discussed in a future post (a great example is the Ruby on Rails ActiveResource). REST clients tend thinner and simpler. With REST you only need a HTTP client library, but SOAP usually requires extra third party libraries. REST makes it easier for clients because a resource can be presented in any format you want (ex JSON, XML, HTML, text, etc) and many REST services provide multiple presentations of the same resource. SOAP uses endpoints and REST uses URIs. An endpoint cannot be changed without breaking clients. URIs can be changed with redirects, which in turn reduces client-server coupling. When using SOAP XML serialization is usually built in, where as with REST external libraries are required to do XML or JSON serialization. REST is asynchronous and SOAP is synchronous. Asynchronous allows for better user experience and performance with clients and also allows clients to handle server errors better.
Development
REST takes full advantage of the features of HTTP, SOAP does not. REST use of the full features of HTTP gives developers more flexibility and power when building a web service. REST is easier to test and debug, partly because responses are human readable. With REST it might be hard to fit some operations on a resource, but in these instances a REST-RPC style service can be used.The table below shows a summary of the comparison of REST and SOAP and which style of web services it best in certain areas:
REST
SOAP
Frameworks/Tools
X
Technology Trend
X
Performance
X
Security
X
Flexibility
X
Clients
X
Maintainability
X
HTTP Standards
X
Conclusion
As you can see there are pros and cons for both SOAP and REST. At BTI we think that REST is best for implementing web services. That doesn't mean that REST is always the best choice, but for many web services it is. As with building any software, choose the implementation that best fits your requirements and needs when building a web service.
REST
Let's take a look at what a REST-style Web Service does for error handling.
In one of our previous blogs we talked about HTTP response codes, if you aren't familiar with them I highly recommend checking it out. Why might you ask...Well a RESTful service always responds with one of these codes for each request. When successful the most common is 200, which means OK, but any 2XX code can be sent for a successful response. The interesting codes regarding errors happen to be 4XX and 5XX codes, these are the ones sent with there is a problem. Typically a 4XX code is sent when the problem is caused by the client, whether a specified resource cannot be found (404) or whether the server cannot respond to the clients request because it is invalid (400). On the other hand 5XX codes are sent when the server cannot respond to a valid request. This could be caused by something as serious as a database that the server relies on being down or even something as simple as a Null Pointer Exception.
It is important to note that most servlet containers will send a default error message in the Response Body with each code but as the developer you are able to specify custom messages with as much information as you want and in any format you wish, just make sure to document the response formats and error conditions!
Here is an example of what you might see if your request generates a 500 Internal Server Error. This is the standard message and as you can see it isn't very helpful.
HTTP 1.1/500 Server Error
A better error response might be something like
HTTP 1.1/500 Server Error
Content-Type: application/json
{"code":500, "message": "Unable to connect to Oracle database"}
or this in the case of a client error.
HTTP 1.1/400 Bad RequestContent-Type: text/xml<?xml version="1.0" encoding="UTF 8"?> <error> <code>400</code> <message>Missing Required Request Parameter "word"</message> </error> </xml>
SOAP
SOAP requests deal with error conditions in similar ways. Since SOAP requests usually play in the same sandbox that RESTful requests do (HTTP) they can respond with the exact same error codes for the exact same conditions. There are actually only a few small differences. As with all SOAP requests, error responses must be sent in the xml format according to the SOAP specifications. Another difference is that according to the W3 SOAP spec, if an error occurs during processing of a SOAP request the server must respond with an HTTP 500 Internal Server Error code along with a SOAP message describing the error. The message is wrapped in the SOAP envelope and is inside a new SOAP fault element indicating the error. An example SOAP error response is below.
It is important to note a few things about this response. The HTTP code is a 500 Internal Server Error according to the SOAP spec, but the faultcode element reports that the error was a client error which in REST would be a 4XX error type. The faultcode element can also contain a SOAP-ENV:Server value. The faultstring element provides a human readable message and is similar to the reason phrased defined by HTTP. There are a few other elements that are defined in the SOAP fault tag and those can be seen in the SOAP specification.HTTP 1.1/500 Server ErrorContent-Type: text/xml<?xml version="1.0"?> <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"> <SOAP-ENV:Body> <SOAP-ENV:Fault> <faultcode>SOAP-ENV:Client</faultcode> <faultstring>Can’t call “getDefinition” because there are not enough parameters.</faultstring> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope> </xml>
Summary
Whether you are building a RESTful or SOAP based Web Service the key points to take away from general Web Service error handling are:
- Follow the SOAP spec: Odds are your client will be using a SOAP client library which will expect errors to be sent according to the spec. Include the correct faultcode and a good faultstring.
- Use the Correct Machine Readable Response Codes: As the developer you can respond with any response code you choose (even ones that are not in the HTTP spec) but as a rule you should only respond with codes that are correct for the error case according to the HTTP spec, e.g. stick to 4XX for client error, 5XX for server error. Note: A too common thing is to always return a 200 OK and include the error message in the body. This is not a good practice, some clients by default will cache 200 responses for efficiency, and you don't want the client to cache the response to a bad request. Good Example: Twitter, Bad Example: Flickr
- Include Human Readable Messages: Do not rely on the default messages, give the client enough information to correct the request and resend it, or let the client know when the request will be successful.
SOAP (Simple Object Access Protocol)
SOAP is a protocol specification for exchanging structured information in the implementation of Web Services. XML is used as the message format and it usually relies on other application layer protocols such as RPC (Remote Procedure Call) and HTTP for message transmission. SOAP provides a basic messaging framework on which Web Services can be built. The XML message consists of three parts: an envelope - which defines what is in the message and how to process it - a set of encoding rules for expressing instances of application-defined datatypes, and a convention for representing procedure calls and responses.
Let's look at an example SOAP request:
POST /dictionary HTTP/1.1
Host: www.bti360.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 147
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.bti360.com/dictionary">
<m:GetDefinition>
<m:Word>happy</m:Word>
</m:GetDefinition>
</soap:Body>
</soap:Envelope>
It's important to know that every SOAP message is sent using a POST when sent over HTTP. In this example you can also see what is meant by RPC when describing a SOAP Web Service. Inside the SOAP body you see "GetDefinition" which looks like an actual method name. Essentially this SOAP message is instructing the server to call a method "GetDefinition" and pass the word "happy" as the method parameter. A key point is that the message is sent in a SOAP envelope which is still wrapped in an HTTP "envelope".
And the response:
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"
xmlns:s="http://www.bti360.com/dictionary">
<env:Body>
<s:GetDefinitionResponse>
<s:definition>delighted, pleased, or glad, as over a particular thing</s:definition>
</s:GetDefinitionResponse>
</env:Body>
</env:Envelope>
As you can see the response is very similar to the request wrapped in the SOAP body and envelope.
REST (REpresentational State Transfer)
For a description of REST you can look at our previous posts.
Let's jump right in and look at a REST-style request for the same operation.
GET /dictionary/happy HTTP/1.1
Host: www.bti360.com
Accept: text/xml Accept-Charset: utf-8
To compare this request with a SOAP request for the same operation you can see the simplicity of it. Instead of specifying a specific method to call on the server to retrieve the data, you simply issue a GET request to the URI of the resource.
Let's look at the response:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<word xmlns:s="http://www.bti360.com/dictionary">
<name>happy</name>
<definition>delighted, pleased, or glad, as over a particular thing</definition>
</word>
The response is very similar to the response to the SOAP request.
In summary the major difference between the request and response formats of a REST-style and a SOAP based Web Service is the rigid requirement of the SOAP message. Each SOAP message must conform to the SOAP specification (link to spec) and include an envelope, encoding style, and body. The body element contains the actual SOAP message, i.e. the server method to call and the argument(s) to use. Compared to SOAP the REST-style requests and responses are very simple. The server "method" to call is determined by the actual HTTP method of the request, and the parameters are either present in the URI (for a GET/DELETE request) or present in the request body for a POST or PUT request. And as discussed in previous blog posts, the actual format of the data can be nearly anything.
In the next REST vs. SOAP post we'll discuss error handling.
Peter Williams, a contributing member of the web service and open source community, wrote a great series of blog posts on versioning RESTful web services using versioned resource representations. It's a great set of posts that everyone who's exposing a RESTful web services should read.
- Versioning RESTful Web Services introduces the reader to the versioning of RESTful web services by versioning your resource representations.
- Versioning RESTful Web Services: Tips & Tricks goes into further detail on the methodology and some related information.
- Finally, REST/HTTP Service Versioning is a response to some arguments against this method of versioning RESTful web services.
Take a look at these postings and see for yourself. And please post any comments or ideas that you may have on the subject of versioning RESTful web services.
First, add two tags to the servlet configuration file:
<context-component-scan base-package='org.bti'/>This tag enables auto-detection of annotated components, such as @Controller and @Repository, in the package specified by the base-package attribute. Then the following tag:
<mvc-annotation-driven/>Using this tag is the best way of jump starting a Spring MVC project. This tag does all of the following:
- Registers the DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter beans which are required for Spring to dispatch requests to @Controller annotated classes.
- Registers those beans to use JAXB to read and write XML and Jackson to read and write JSON if JAXB and Jackson are in your classpath.
- Registers other converters to convert different number formats and date/time formats.
- @Controller – Let's Spring know that this class will serve as a controller in the MVC pattern. Spring will search these classes for methods annotated with @RequestMapping.
- @RequestMapping – Used to map URLs onto an entire class or method. If the annotation is used at the class level @RequestParams can be used to narrow the mappings. Mappings can also be narrowed by the request method (GET/POST/DELETE/PUT)
- @PathVariable – Used to map variables in the URI in the @RequestMapping to method parameters
- @RequestBody – Used to map the request body onto a variable. Can also map to Beans such as our Word object, using either JAXB or Jackson to convert the data from either xml or json. Uses the content type to determine the format.
- @ResponseBody – Used to let Spring know that you want whatever you are returning from the method to be written to the response, and the response status will be OK by default. The output format depends on the Accepts header of the request.
- @ResponseStatus – Lets Spring know what status to write to the response.
- @ExceptionHandler – Tells Spring that a type of exception thrown in a controller should be handled by the annotated method. Used along with @ResponseStatus, this annotation also gives the ability to have a request return different statuses based on the outcome of the request.
- @RequestParam – Maps a request or query parameters to method parameters.
In two of our previous blogs we talked about the four different types of HTTP requests that are important when working with RESTful Web Services. In this blog I'd like to take a closer look at the POST and PUT requests; requests that are used to create and update resources. The HTTP 1.1 spec states that
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. […] The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.
and
The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.
So a POST can be used to create and a PUT can be used to create or update, but it's really not that cut and dry. The REST architectural style doesn't really mention anything about which should be used for which but the de-facto standard is to use a POST for a create operation and a PUT for an update operation. The main reason for this is idempotency, which is also the main difference between these two operations.
As a reminder, an operation is idempotent if a sequence of two or more of the same operation results in the same resource state as would a single instance of that operation. According to the HTTP 1.1 specification, GET, HEAD, PUT and DELETE are idempotent, while POST is not. That is, a sequence of multiple attempts to PUT data to a URL will result in the same resource state as a single attempt to PUT data to that URL, but the same cannot be said of a POST request. This is why a browser always pops up a warning dialog when you try to refresh a POSTed form. “Are you sure you to buy more airline tickets!?”

Multiple POST requests can cause side-effects such as multiple resources being created.
Let's look at some example requests.
POST /dictionary
<?xml version="1.0" encoding="UTF-8"?>
<word>
<name>happy</name>
<definition>delighted, pleased, or glad, as over a particular thing</definition>
</word>
This request adds a word, happy, to the dictionary container. Multiple requests could create multiple words and the returned Location URI for the new resources would be different, i.e. /dictionary/happy/1 and /dictionary/happy/2. This happens because with a POST the server is assigning the URI under the dictionary container to insure that the URI is unique to the resource.
PUT /dictionary/happy
<?xml version="1.0" encoding="UTF-8"?>
<word>
<name>happy</name>
<definition>thrilled or ecstatic...now look those up.</definition>
</word>
This request updates the resource at /dictionary/happy with the contents of the xml document in the request body.
So in summary use POST to create a resource by letting the server generate the unique URI and use PUT to update a resource since you already know the unique URI.
The subject of media types has been glossed over in some of our recent blogs and screencasts. In this blog I'd like to focus on what media types are and give some basic guidelines for using them in your RESTful web services.
A media type is a two-part identifier for file formats on the Internet. Some examples of very common media types are:
- text/xml
- text/html
- audio/mpeg
- video/mp4
- image/jpeg
A list of registered media types is made available on the web by the Internet Assigned Numbers Authority (IANA). So how does this relate to RESTful web services? As you already know RESTful web services are focused around resources, and service clients interact with those resources through representations. Every representation of a resource is a media type.
Here are a few guidelines regarding how you should represent the resources in your web services using media types:
- Whenever possible you should use existing media types to represent your resources. This will open your web service up to many more clients, and allow for much easier integration. It makes perfect sense. If you had a resource that was a person and you wanted one representation of the resource to be a picture of the person, would you send back that picture using the "image/jpeg" media type or would you make up your own image format and use that? I think the answer is pretty obvious.
One commonly used media type in RESTful web services is the ATOM Syndication Format (application/atom+xml). ATOM was essentially designed as an improved format for web feeds. But its flexibility has made it a great media type for representing resource collections. By using the ATOM media type to represent your collection resources, you immediately open your service up to a huge range of clients that already know how to parse ATOM XML.
- Ensure that your media types accurately represent your resources. So I'm going to pick on one of our own previous blog postings. In the last blog on HATEOAS we used the following request / response example:
Client Request:
GET /dictionary/happy HTTP/1.1 Accept: application/xml
Service Response:
So here our client has asked for a resource represented using the 'application/xml' media type. And our service has responded with the representation in XML format. You may wonder: "What's the problem? 'application/xml' is a valid and common media type." That it is, but unfortunately, if I go and read the specification for the 'application/xml' media type I will be able to parse the response above, but I won't have any idea what it means.Content-type: application/xml <?xml version="1.0" encoding="UTF-8"?> <entry> <word>happy</word> <part-of-speech>adjective</part-of-speech> <definition>delighted, pleased, or glad, as over a particular thing</definition> </entry>
The same would apply if I had sent back 'application/json'. So what is the best thing to do? First, check the registered media types to see if there is a public and widely used representation for dictionary entries that meets your needs. If you find one that nearly meets your needs, hopefully you can extend it. If you don't find one, then you'll have to create your own media type. Here's how the previous request might look if I had used a custom media type for a dictionary entry:
Client Request:GET /dictionary/happy HTTP/1.1 Accept: application/dict-entry+xml
Service Response:Content-type: application/dict-entry+xml <?xml version="1.0" encoding="UTF-8"?> <entry> <word>happy</word> <part-of-speech>adjective</part-of-speech> <definition>delighted, pleased, or glad, as over a particular thing</definition> </entry>
As you can see, the data returned here is the same. The key difference is in the 'Content-type' header. The 'application/dict-entry+xml' media type would be well-defined and clearly inform the client of how to interpret the response.
- Ensure all your media types are well documented and publicly available. This is not much of an issue if you use a registered media type to represent a resource. However, if you are using custom media types or extending a registered media type, it is imperative that you very clearly document the media type and make that documentation publicly available to any potential service clients.
This is one of the things that we mentioned when we discussed HATEOAS. The two pieces of information that a client needs to know to use a RESTful web service are the starting point and how to interpret the information displayed. So this is where nearly all of our service documentation will come from: documenting our media types. This can't be stressed enough. DOCUMENT YOUR MEDIA TYPES!!!
That's about it for media types at this point. There may be more to come in the future, but I'll let you chew on all of this for now. Keep on learning, and pass your new knowledge on.
Hypermedia as the engine of application state. Wow, that's a mouthful. Many people shorten the phrase to HATEOAS, which is only slightly less of a mouthful (or keyboardful), but it's what we've got. HATEOAS is one of the core principles of the REST architectural style. When the principle is followed correctly it provides several key benefits to a web service.
Let's break the principle down, talk a little bit about why it's important, and then we'll get into the nuts and bolts of how to implement it in your web service.
What?
Hypermedia is really just a fancy word for a link. It is an object that has within it pointers or links to other pieces of media, which could be text, images, audio or video.
We all know a link when we see one:
- You click on a picture of a movie poster and the trailer for that movie is played.
- You click the "Save" button for your order at an online bookstore and your order is processed.
- You select a phrase in Spanish and it is read aloud to you.
HATEOAS simply means that the client should be guided through your application using links. This is not a new concept. The web is built on this principle. Without it the internet would have been an abysmal failure. Because of HATEOAS, all I need to know to do my searching is google.com. All I need to know to handle my finances is mint.com. All I need to know to find a great place to work is bti360.com. When a web application follows the HATEOAS principle, all I need to know to use it is the starting point and how to interpret the information displayed once I get there.
Why?
As we've said before, a web service is simply a web site designed to be consumed by machines instead of people. So it makes sense that a web service can and should derive the same benefits from HATEOAS as all the web sites on the internet. Those benefits are:
- Limited prior knowledge for clients to use the service. They only need the starting point and the ability to interpret at least one of your services resource representations.
- Increased flexibility. By limiting the client's prior knowledge, it leaves many areas of your service implementation free to be changed when necessary.
How?
Ok, you've bought in to the whole HATEOAS principle and want to add it to your web service. Let's show you how to do just that.
I'm going to continue with a dictionary/thesaurus example that was begun in previous blogs. So below we have a client request for a word in our dictionary, and the service response:
Client Request:
GET /dictionary/happy HTTP/1.1 Accept: text/xml
Service Response:
<?xml version="1.0" encoding="UTF-8"?>
<entry>
<word>happy</word>
<part-of-speech>adjective</part-of-speech>
<definition>delighted, pleased, or glad, as over a particular thing</definition>
</entry>
So let's say our service also provided synonyms. In the above example there is no mention of synonyms for the word "happy". In that situation, the client would have to know ahead of time that our service provided synonyms, and what the URL was to retrieve the synonyms for the word "happy".
Now let's look at the same request, only this time the service is going to follow the HATEOAS principle:
Client Request:
GET /dictionary/happy HTTP/1.1 Accept: text/xml
Service Response:
<?xml version="1.0" encoding="UTF-8"?> <entry> <word>happy</word> <part-of-speech>adjective</part-of-speech> <definition>delighted, pleased, or glad, as over a particular thing</definition> <link rel="synonyms" type="text/xml" uri="http://example.com/dictionary/happy/synonyms" /> <link rel="antonyms" type="text/xml" uri="http://example.com/dictionary/happy/antonyms" /> </entry>
Now we've embedded in our entry a link to that word's synonyms. If the client understands our entry representation (including what the "synonyms" relationship means), and understands the data type for the synonyms link, then the synonyms can be retrieved simply by following this link. It's really that simple.
Wrap Up
Following the HATEOAS principle is important for any RESTful web service. While there is no way to eliminate out-of-band knowledge required for your client's, HATEOAS is a great start towards reducing it. Come back next week and we'll take about another way to lower the barrier to entry for your clients: Media Types.
Server: "Silly client, you think it's going to be that easy? If you ever want to see JSON alive again, you're going to have to give me one million dollars."
Client: "How do I even know that you have JSON?"
Server: "Why don't you ask him yourself?" [Puts JSON on the line]
JSON: { "voice":"HELP ME!!!", "emoticon": ":-o" }
Client: "I'll get the money..."
We've all been a part of these sorts of heated content negotiations in the past, and want to avoid them in the future. That's why it's important for HTTP clients and servers to communicate in a clear and consistent manner which representation will be returned for a request.
As the client, you are free to specify the representation that you prefer via the HTTP Accept header. The server will read in the header, and make its best judgment on which representation to return.
This negotiation could look something like:
Client Request
GET /dictonary?synonym=happy HTTP/1.1
Accept: application/json
Server Response
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 512
{"status": "OK", "synonyms": [{"synonym": "chipper"}, {"synonym": "glad"},
{"synonym": "pleased"}, {"synonym": "tickled"}]}
However, if the requested representation is not available, the server is free to either send back the representation it does have, or to return an HTTP Response Code 406 (not acceptable). This exchange between the client and server is the actual negotiation.
Representation Preference
It is important to note that the client is not limited to listing one representation in the Accept header. In fact, the header can include a comma-delimited list of acceptable content types, each optionally with a quality value for preference ranking. The quality values range from 0-1, with 1 being the most preferred representation. Take the following example:
Accept: application/json;q=1, text/html;q=0.5; application/xml;q=0.1
This lets the server know that the top preference is for "application/json", followed by "text/html", and finally "application/xml".
Here are some other things to keep in mind when specifying representation preferences:
- A representation is composed of the type and the subtype, in the following format <<type>>/<<subtype>> (ex. "text"/"html")
- A "*" represents a wildcard (technically referred to as a media-range). "*/*" means any representation available. "application/*" means any subtype of application.
- A (blank) Accept header means that any representation is acceptable
There are several other, less known rules with regard to representation preference; it is recommended that you see the HTTP/1.1 Specification for more details.
Alternative Negotiation
A common alternative mechanism for requesting a specific representation is to append an extension to the resource being requested, and leave the Accept header blank. Using this approach the original request from above would be modified to read like the following:
GET /dictonary.json?synonym=happy HTTP/1.1
Note: Although common, this alternative for content negotiation is not an HTTP 1.1 compliant mechanism for requesting representations.
Summary
Resources can have several different representations. It is up to the client and server to negotiate (hopefully without kidnapping and ransom requests) which representation will be returned. The client does this by listing out which representation it prefers in the HTTP Accept header. If available, the server will return the requested representation.
2xx Series
The most common in this series for dealing with RESTful Web Services are 200 OK and 201 Created. The 200 OK code is the standard response code for a successful HTTP request. When a GET, PUT, or DELETE request is successful this is the response code returned. Since a POST request is used for creating a resource, the 201 Created status code is returned. With a successful POST the location or URI of the newly created resource is also returned in either the response body or as a response header. As a habit, I return this in the response header under the "Location" key.
3xx Series
The 3xx series of codes mean that the client must take additional action to complete the request. The 301 Moved Permanently is a code you may see after doing a POST or PUT to create or update a resource. This means that the resource has a new URI and you must use it in the future to access the resource. The new URI will also be returned as part of the response. Another one you may see often is the 304 Not Modified code. If the resource has not been modified since it was last requested, the server sends this code to let the client know to use the cached resource, to save time and bandwidth.
4xx Series
The 4xx series correspond to requests that could not be fulfilled due to a client error. Everyone should be familiar with the 404 status code, that is the common code seen when a resource cannot be found. 400 Bad Request is also a code you will see when the request you send to the server cannot be fulfilled, an example being executing a GET request on http://www.bti360.com/dictionary when you didn’t specify a resource to GET. 401 Not Authorized and 403 Forbidden are codes that can be used to let the client know that they do not have access to the resource that was requested.
5xx Series
The 5xx series is a catch-all for anything that is the server’s fault. Not much can be said here except that the server should send an appropriate code and message to let the client know whether the request should be retried.
Summary
| Response Code |
Meaning |
| 200 | OK. A standard successful response. |
| 201 | New resource created. |
| 301 | Redirection to new URI. |
| 304 | Cached resource can be used. |
| 400 | Client sent bad request. |
| 401 | Unauthorized. (needs authentication) |
| 403 |
Forbidden. (authentication won't help) |
| 404 | Resource Not Found |
| 500 |
Internal server error |
These codes are the most important to know and use when producing and consuming RESTful Web Services. The key point to remember is that 2xx is good, 4xx is the client’s fault, and 5xx is the server’s fault.
Now that Topher figured out how to make an HTTP request to a RESTful Web Service, he needs to know all about resources and representations. Resources are the objects that a web services exposes to the world. The resources are maintained and controlled by the service. A resource could be data in a database, a physical object such as a person, or a conceptual object like "the most recent blog posting."
Clients interact with resources through representations. And a resource can have many different types of representations. Examples of common representations are "text/html", "application/xhtml+xml", "application/xml", "application/json", "image/jpeg", "image/gif", and "audio/mpeg". RESTful web services can send and accept representations of resources in any of these content-types that the service chooses.
One of the reasons RESTful web services are popular is because they can easily provide many representations for a resource. Many RESTful web services provide the ability to return the results of a request in multiple formats by specify the format as part of the request. RESTful services provide a default format if none is specified on the request. Some web service implementations like SOAP only allow one response format. Lets look at some common response formats for an example GET request:
GET http://www.bti360.com/dictonary?synonym=happy
From a previous post we know that this request will return synonyms for the word 'happy'. Now lets see a few possible representations for this request. In the following examples note that the response format is specified on the HTTP request.
XML
GET http://www.bti360.com/dictionary/happy/synonyms.xml
The XML representation in the response looks like
<?xml version="1.0" encoding="UTF-8"?>
<synonyms>
<synonym>chipper</synonym>
<synonym>glad</synonym>
<synonym>pleased</synonym>
<synonym>tickled</synonym>
</synonyms>
JSON
GET http://www.bti360.com/dictionary/happy/synonyms.json
The JSON representation in the response looks like
[{"synonym": "chipper"}, {"synonym": "glad"}, {"synonym": "pleased"}, {"synonym": "tickled"}]}
HTML
GET http://www.bti360.com/dictionary/happy/synonyms.html
The HTML representation in the response looks like
<ul>
<li>chipper</li>
<li>glad</li>
<li>pleased</li>
<li>tickled</li>
</ul>
CSV
GET http://www.bti360.com/dictionary/happy/synonyms.csv
The CSV representation in the response looks like
chipper,glad,pleased,tickled
As you can see RESTful Web Services allow for many possible representations of the same resource. They can be standard or you can create your own. This flexibility allows many types of clients to access RESTful services. However, flexibility can also be dangerous. Whenever possible it is recommended that a RESTful web service use standard representations for their resources. This allows clients to quickly and easily integrate with your service.
Let's look more closely at these types of requests.
| Method | Intended Use | Safe | Idempotent |
|---|---|---|---|
| GET | To retrieve a resource |
Yes | Yes |
| POST |
To create a resource | No | No |
| PUT | To change the state of or update a resource | No | Yes |
| DELETE | To remove or delete a resource |
No | Yes |
GET
The GET request is used by the client to retrieve a resource or execute a query that will allow the server to retrieve a set of matching resources. A GET request should be free of side effects, meaning it does not change the state of any resource on the server.
A GET request URI looks like
GET http://www.bti360.com/dictionary/set
GET http://www.bti360.com/dictionary?synonym=happy
The first URI is a URI for the definition of set. This request will return the resource with "set" as the identifier. The second URI is a URI for a query for words in the dictionary that are synonyms for happy. This request may return multiple resources such as "content, joyful, chipper, peppy" and the resources are returned to the client in the Response Body.
POST
The POST request is used to create a resource on the server. A POST request URI looks like
POST http://www.bti360.com/dictionary
This URI looks very similar to the GET URI except that it contains no resource identifiers or a query string. Dictionary is the parent resource and a resource create with this POST request will be stored as a child resource of dictionary. With a POST request the data describing the resource is sent along with the request in something called the Request Body. A POST is neither safe nor idempotent because by definition the request creates a resource on the server, and multiple requests could create multiple resources.
PUT
The PUT request is used to update or modify a resource on the server. A PUT request URI looks like
PUT http://www.bti360.com/dictionary/set
You may be thinking "well that looks very similar to a POST request" and you would be right. The PUT request looks identical to the POST request with one main difference. With a POST request the server generates a unique identifier for the new resource and for a PUT the unique identifier is already generated and known by the client. If the client was allowed to generate the id then there would be no guarantee that the id was unique.
DELETE
The DELETE request is used to delete or remove a resource from the server. A DELETE request URI looks like
DELETE http://www.bti360.com/dictionary/set
This requests that the server delete the resource identified by this URI, so it would delete "set" from the dictionary.
Safe and Idempotent Methods
There is one more final key point about safe and idempotent methods. These methods are defined to have these qualities in the HTTP/1.1 Spec and the client expects these methods to behave this way. But the server is not technically limited by this so it is up to the developer to ensure that the server software also follows these rules.
http://www.bti360.com/dictionary/set
"Wait a second, that looks just like a website address?" they exclaimed, wanting to know what it all meant. Resources and verbs, my friends, think resources and verbs.
Resources are the actual "things" that are being exposed in a web service. In the example above, "/dictionary" is the resource and "/set" is a sub-resource. What can we do with these resources? Well, that's where the verbs come in.
RESTful web services take advantage of common HTTP methods in order to perform operations on a resource; these HTTP methods are referred to as REST verbs. The most commonly used verbs include:
|
REST(HTTP)
|
Operation |
| POST | Create |
| GET | Retrieve |
| PUT | Update |
| DELETE | Delete |
One nice characteristic of REST verbs is that the URI does not change when different operations are performed. For example, the same URI given at the top can be used to:
- Create the word set in the dictionary we use the HTTP POST
- Retrieve the definition of the word set in the dictionary we use the HTTP GET
- Update the definition of the word set in the dictionary we use the HTTP PUT
- Delete the word set from the dictionary we use the HTTP DELETE
So Snook and Topher, what did you learn today? The "web address"
that you saw is actually a REST URI that can be used to perform
interesting actions (create, read, update, delete) on a particular
resource. How about that? You both now know some basics for interacting
with a RESTful web service.
Please note: REST URI's should not be pre-constructed by client code. In fact, they should be treated as opaque identifiers that are meant to be discovered by following hyperlinks (the HATEOAS REST constraint will be discussed later... so stay tuned)
*A URI is the name and web address of a resource (an identifier)
So my colleague Snookie asked me the other day, "What's this REST thing I keep hearing about?" So I said "Well Snook, Representational State Transfer, or REST, is an architectural style for distributed hypermedia systems." Snookie, being the intelligent software engineer that she is, quickly responded: "Thanks, that really cleared things up."
The End.
Actually, that never happened, and Snookie doesn't really exist, but stories are supposed to make things more interesting. Did it work?
So if you've read this far you must really want to know more about REST, here we go. Let's start with some background. The quoted definition back there for REST was from a guy named Roy Fielding, who coined the term REST in a dissertation that he wrote all the way back in 2000. "So long ago?" you might ask. Yes, the REST architectural style, is essentially a set of constraints placed upon an architecture to evoke certain desirable properties. The particular constraints of REST were chosen to specifically guide the growth of the web.
So what does all this have to do with web services? Well, on a late night about four years ago this guy named Topher was working on a SOAP web service for his online bookstore. All the sudden his WSDL exploded, XML went everywhere and all his envelopes were destroyed. After that night he vowed to never abuse HTTP in that way again. Ok, so I just made up another story, its kind of addictive.
But if Topher was a real person, what he would have meant was that his web service really should take advantage of the system that its being run on, THE WEB! That's where RESTful web services come in. As I said before, the constraints of REST were used to guide the development of the web (HTTP, URIs, HyperText, etc.). RESTful web services take advantage of the architecture of the web, where as other types of web services (SOAP, RPC) simply ride on top of it.
Let's look at an example. One of the constraints of the REST style is the uniform interface. A uniform interface between client and server makes for a simpler, decoupled architecture. One aspect of a RESTful web service's uniform interface is the set of HTTP verbs. HTTP defines several actions that a client can take on a resource the most common of which are GET, POST, PUT, and DELETE. Each of these actions is very well defined and clear on what it does and does not do. A RESTful web services strictly adheres to the rules for these actions. This allows for every client to know the precise meaning and ramifications of its requests.
In contrast, a SOAP web service running on the web uses the POST action for every request. This obscures the nature of the request from the outside world and ignores the design of HTTP.
Another constraint of the REST architectural style is the cache constraint. The cache constraint requires that data within a request be explicitly labelled as cacheable or non-cacheable. The web implements this constraint through standardized HTTP headers and directives. RESTful web services can take advantage of this work, allowing any client or intermediary layer to cache requests appropriately.
Hopefully at this point I've given you a general overview of what REST is and why it makes sense. This is just the tip of the iceberg my friends. I'll be back soon to give you all sorts of practical information about designing and implementing RESTful web services.
So run along and tell your boss's boss that REST is going to solve all your problems!
JP
Cultivate Collaboration, Drive Innovation
DISCLAIMER: I assume no responsibility for you telling your boss's boss that REST will solve all his problems.



ShareThis