Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 4
REST uses URLs to identify addresses for resources. (This is the first thing most people learn about REST and where some stop, unfortunately.) These names are not intended as arbitrary handles (although URI opacity remains a hotly debated topic), but more as logical paths through information spaces. An information space is a vector through the data someone cares about. Each step along the way can mean something in a particular domain. When you try to resolve the name at each level, you expect to get something back -- either a summary or explicit information. As you traverse the path from more generic to more specific, you are actually navigating some shape to the information.
As an example, suppose you are modeling an information system representing a library's inventory. http://someserver/book could map to a RESTful engine that would interpret that request as the name of all the books in the library. You may not
actually want to retrieve a representation of all of those books (although with pagination, that is clearly an option). Instead,
you might return a document representing further classifications of the books or a description of how to invoke the library
collection services in different ways. When the request is made from a browser, you might return HTML documentation about
how to invoke the service. If you use a programmatic library such as the Restlet client API or Apache HTTP Client, an XML
representation of the next level's options might make sense; it could include either simple, popular categories (such as biography,
economics, or fiction) or more formal classification schemes like the Dewey Decimal system.
Information clients would like to navigate the collection however they want. They might prefer to browse by genre, publication date, author, ISBN number, or their own checkout history. REST does not require you to establish a one-to-one mapping between the resources in question and the paths to get there. These are all reasonable ways to find what a library patron might be looking for:
http://someserver/book/genre/horror
http://someserver/book/date/2006
http://someserver/book/author/Vonnegut
http://someserver/book/isbn-10/0671799320
http://someserver/book/isbn-13/978-0671799328
http://someserver/book/patron/1234566
In this RESTful architecture, it is unlikely that patrons will actually type these URLs (although there is no reason they can't). Rather, they will discover them as they browse categories or view search results. As you return one type of result, you can include hyperlink references to the genre, publication date, and author as well so they simply have to click through to explore. The interaction style of the Web and the interaction style of RESTful services work together nicely.
You can compound these paths when it makes sense, but you should be careful when you try this. http://someserver/book/patron/1234566/2008 could narrow the list of books returned for a particular patron to those checked out in 2008. You could further refine it
by month. However, when you navigate a path, you should not change what kind of data is returned. For example, starting out with /book, users would expect to receive one or more book results. http://someserver/book/author/Vonnegut/Kurt should not return biographical information about the satirist Kurt Vonnegut, but rather a collection of his books maintained
by the library. You would want to use a different URL for a biographical information space to return more information about
him -- perhaps something like http://someserver/author/Vonnegut/Kurt.
The URL in this context:
Resolving these URLs is essentially the act of issuing a query. It is easy to cache results when you can give names to them; the RESTful engine can track explicitly what is being asked for and how often. By identifying questions that have already been answered, you avoid pounding the database, which can help reduce back-end costs. Again, with the layered architectures you have been building, you could easily build caching into a persistence layer. If processing (for example, sorting, styling, or filtering) is done on the data, you would have to build separate caching systems to handle each of those states. With REST you can give a logical name to the processed data as well and achieve the same potential for caching there that you did on the raw data. It is known through the logical name, so it can be cached based on the result.
Finally, giving logical names to information allows you to pass references to data, rather than the data itself. This not only prevents you from overwhelming middleware with large results; it also prevents orchestrated services from needing to know who has access to what in different application scopes. Any system that tries to resolve the reference can be separately challenged by an authorization and authentication system. Only business systems that have a need to get to sensitive information (such as customer checkout histories) can actually get to it. This helps reduce the burden of role-based access control and increases the fidelity of how you enforce protection of sensitive information. This architecture goes a long way toward reducing the burden of regulatory compliance for use of credit-card, medical-history, or other private data.
URLs also help meet REST's scalability goals, because they address the need for stateless requests. Ultimately, we achieve horizontal scalability by throwing more server hardware at our infrastructure. Any of these servers must be able to handle the request. Any state not maintained in the database or a shared memory system (such as Terracotta) would be lost in the transition from one server to another. That would prevent you from being able to bounce the requests around any piece of hardware. For a request to be stateless, everything needed to satisfy the request must come in as part of the request, including the URL, headers, optional body, and any query parameters. The server that receives this request then has every bit of input necessary to handle it.
Once you have good, logical names that reflect the various shapes of information users care about, you need a way of letting your RESTful service manipulate it. This is where the four REST verbs -- GET, POST, PUT, and DELETE -- come in. Developers coming to this way of thinking from the world of Java APIs and SOAP feel constrained by the availability of only four actions. This reaction is usually a smell that you are thinking about invoking behavior, not manipulating information. GET, POST, PUT and DELETE are suitable for information management. Web services for arbitrary behavior addressed through URLs is not REST. Web services that allow the retrieval and modification of logically named resources that mean something to someone is what REST is about. The HTTP protocol and its verbs are the most common implementation of the REST verbs, but other bindings are not difficult to imagine.
RESTafarians are quite explicit about keeping names as nouns. It is entirely possible to create a URL like http://someserver/getemployee&id=12345677 that maps to some back-end query. But if you want to update this resource in an application, you would need to come up with
a separate service to manipulate the content. You have forked the relationship between the data and the means to manipulate
it. It is suddenly less easy to apply a clear, declarative policy for information-based access control. If instead you use
http://someserver/employee/12345677, you can issue a GET verb to retrieve the data and update it with PUT, POST, and DELETE.
More