Вы находитесь на странице: 1из 68

An adventure in being RESTful

Ralph Shnelvar ralphs@dos32.com

Youve been programming in Rails for a while but much of what it does seems like magic. Youve heard about REST but it all seems very confusing.

Ralph Shnelvar ralphs@dos32.com

REST is a style of programming for the Web. If everyone programmed using REST, the Web could run faster. If everyone programmed using REST, programming for the Web would be faster and more self-documenting. REST allows you to treat resources on the Web at a higher level of abstraction than using ad hoc HTTP. Its like being able to handle files on a disk drive as files in directories as opposed to thinking about where to place the bytes of a file on a disk. The concepts of URIs and Resources are intimately linked. Just because a programmer uses the RESTful interfaces provided by RAILS does NOT mean that one is being RESTful.
Ralph Shnelvar ralphs@dos32.com

I will be describing REST at a high conceptual level. Dont expect to find code here. Many of the following slides contain a lot of text. I will summarize the slide or just skip it to hold it to 45 minutes. The additional text is there to give the reader more in-depth information that can be digested later. There are 68 slides in this presentation. Questions will be answered at the end of the presentation.

Ralph Shnelvar ralphs@dos32.com

I'm calling this "connectedness" because "hypermedia as the engine of application state" makes the concept sound more difficult than it is.
RESTFUL Web Services pg. 95 Leonard Richardson & Sam Ruby

A RESTful web service will provide hyperlinks to guide the consumer (a human or a program) of the service hyperlinks to other useful resources.

In the next two slides, experts cannot even agree if REST is an architectural style or not! In the first of the two slides, REST is a set of design criteria and NOT an architecture (much less an architectural style).
In the second, REST is an architectural style!

.. REST is not an architecture: it's a set of design criteria. You can say that one architecture meets those criteria better than another, but there is no one "REST architecture."
RESTFUL Web Services pg. 80 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

Since REST is an architectural style not a well-defined specification, it leaves a lot for interpretation. However, with the increased proliferation of the RESTful style in popular web APIs, some common traits have emerged which are now recognized as best-practices in RESTful web API design.

http://www.freshblurbs.com/pragmatic-restful-api-design

I took Roy Fieldings thesis - hes the author of rest. Who read the thesis? Did you learn anything about REST from the thesis? ... because I didnt.

This video has nothing to do with Create, Read, Update, Delete (CRUD) http://www.confreaks.com/videos/719-rockymtnruby2011-crud-is-not-rest-hypermedia-for-y-all

One can say that Ruby is a more objected oriented language than C++.
Some websites and web services are more RESTful than others. Its highly subjective.

* Dr. Fieldings name is the first name on RFC 2616 (HTTP/1.1)

www.infoq.com/news/2011/04/http-1.2-released actually has some pretty decent information.

HTTP 1.1 and the HTTP 1.1 verbs are defined in RFC 2616 written in June, 1999.

HTTP is a document-based protocol, in which the client puts a document in an envelope and sends it to the server. The server returns the favor by putting a response document in an envelope and sending it to the client. HTTP has strict standards for what the envelopes should look like, but it doesn't much care what goes inside [the envelope].
RESTFUL Web Services pg. 5 Leonard Richardson & Sam Ruby

Well, sort of. The contents of the envelopes in a welldesigned RESTFUL application will generally have links suggesting where to go to next.

Those links do NOT have to be HTML. They can be, for instance, URIs in a JSON or XML document.

Roughly speaking, a resource is a unique thing or a concept that can be accessed by a URI.

Defining what a resource is, is like trying to define beauty. One knows it when one sees it.

Remember that a resource is anything

interesting enough to be the target of a hypertext link.


Anything that might be referred to by name ought to have a name.
RESTFUL Web Services pg. 112 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

Web services commonly expose three kinds of


resources: 1. Predefined one-off resources for especially important aspects of the application. 2. A resource for every object exposed through the service. 3. Resources representing the results of algorithms applied to the data set.

RESTFUL Web Services pg. 112-113 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

This includes top-level directories of other available resources. Most services expose few or no one-off resources.
Example: A web site's homepage. It's a one-of-a-kind resource, at a well-known URI. which acts as a portal to other resources. The root URI of Amazon's S3 service (https://s3.amazonaws.com/) serves a list of your S3 buckets. There's only one resource of this type on S3. You can GET this resource, but you can't DELETE it. and you can't modify it directly: it's modified only by operating on its buckets. It's a predefined resource that acts as a directory of child resources (the buckets).
RESTFUL Web Services pg. 113 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

One service may expose many kinds of objects, each with its own resource set.
Most services expose a large or infinite number of these resources. Example: Every S3 bucket you create is exposed as a resource. You can create up to 100 buckets, and they can have just about any names you want (its just that your names cant conflict with anyone else's).
RESTFUL Web Services pg. 113 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

This includes collection resources, which are usually the results of queries. Most services cither expose an infinite number of algorithmic resources, or they don't expose any.
Example: A

search engine exposes an infinite number of algorithmic resources. There's one for every search request you might possibly make. The Google search engine exposes one resource at http://google.com/search?q=jellyfish

(that'd be "a directory of resources about jellyfish") and another at http://google.com/search? q=chocolate ("a directory of resources about chocolate"). Neither of these resources were explicitly defined ahead of time: Google translates any URI of the form http://google.com/search?q={query} into an algorithmic resource "a directory of resources about {query}."
RESTFUL Web Services pg. 113 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

Conceptually, if you can write a URI for it and you get something useful back from the server, its a resource.

A resource is like the contents of a file. A file system generally does not care whats in a file. A representation is like viewing a JPEG as a picture. A URI is like a file name A directory is a URI for a collection of files.

A RESTful application allows your to operate on files and directories without caring about the exact contents of the files and directories.

1) Predefined one-off resources, such as your service's home page or a static list of links to resources. A resource of this type corresponds to something you've only got a few of: maybe a class in an object-oriented system, or a database table in a database-oriented system. 2) A large (possibly infinite) number of resources corresponding to individual items of data. A resource of this type might correspond to an object in an object-oriented system, or a database row in a databaseoriented system. 3) A large (probably infinite) number of resources corresponding to the possible outputs of an algorithm. A resource of this type might correspond to the results of a query in a database-oriented system. Lists of search results and filtered lists of resources fall into this category.
RESTFUL Web Services pg. 228

There are some difficult cases in resource design, places where it seems you must manipulate a resource in a way that doesn't fit the uniform interface. The answer is almost always to expose the thing that's causing the problem as a new set of resources. These new resources may be more abstract then the rest of your resources, but that's fine: a resource can be anything.

RESTFUL Web Services pg. 228

If you expose HTTP's uniform interface as it was designed, you get two useful properties for free. When correctly used, GET and HEAD requests are safe. GET, HEAD, PUT and DELETE requests are idempotent. Safety
A GET or HEAD request is a request to read some data, not a request to change any server state. The client can make a GET or HEAD request 10 times and it's the same as making it once, or never making it at all.

Idempotence
Idempotence is a property where making a request two or more times is the same as making it once. Server state changes the first time but does not change after that.
RESTFUL Web Services pg. 102

POST requests are the fly in the ointment that is reliable HTTP. GET, PUT, and DELETE requests can be resent if they didn't go through the first time, because of the restrictions HTTP places on those methods. GET requests have no serious side effects, and PUT and DELETE have the same effect on resource state whether they're sent once or many times. But a POST request can do anything at all, and sending a POST request twice will probably have a different effect from sending it once. Of course, if a service committed to accepting only POST requests whose actions were safe or idempotent, it would be easy to make reliable HTTP requests to that service.
RESTFUL Web Services pg. 283

POST Once Exactly (POE) is a way of making HTTP POST idempotent, like PUT and DELETE. If a resource supports Post Once Exactly, then it will only respond successfully to POST once over its entire lifetime. All subsequent POST requests wall give a response code of 405 ("Method Not Allowed"). A POE resource is a one-off resource exposed for the purpose of handling a single POST request.
POE was defined by Mark Nottingham in an IETF draft that expired in 2005. I think POE was a little ahead of its time, and if real services start implementing it, there could be another draft. You can see the original standard at http://www.mnot.net/drafts/draft-nottingham-http-poe-00.txt

RESTFUL Web Services pg. 283

There are many [other] ways to define a [map] service in a RESTful and resource-oriented way. It all depends on how you split the data set into resources, what representations you define for those resources, and how you tie them together with hypermedia.
RESTFUL Web Services pg. 166 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

Unlike some other frameworks. Rails doesn't let you define your resources directly. Instead, it divides up an application's functionality into controllers: it's the controllers that expose the resources. The first path variable in a request URI is used to route Rails to the appropriate controller class. For instance, in the URI /weblogs/4 the "weblogs designates the controller: probably a class called WeblogController. The 4" designates the database ID of a particular weblog. In previous versions of Rails, programmers defined RPC-style methods on controllers: methods like rename and delete. To rename a weblog you'd send a GET or an over-loaded POST request to /weblogs/4/rename. Rails applications, like most web applications, were REST-RPC hybrids. In Rails 1.2, programmers define special controller methods that correspond to the methods of HTTP's uniform interface. For instance, sending a GET to /weblogs triggers the WeblogController's index method, which is supposed to retrieve a list of the weblogs. Sending a POST to the same URI triggers the WeblogController#create method, which creates a subordinate resource beneath /weblogs: say, a weblog with a URI of /weblogs/4. The Rails controller exposes a resource"the list of weblogs"that responds to GET and POST. As you'd expect, when you POST to the "list" resource you get a subordinate resource: a new weblog. The subordinate resource also supports the uniform interface. If you wanted to rename a weblog in an RPC-style service, you might POST a new name to /weblogs/4/rename. Under a RESTful regime, you PUT a new name to /weblogs/4, triggering the WeblogController#update method. To delete a weblog, you send a DELETE request to its URI triggers the controller's WeblogController#destroy method. There's no need to expose an RPC-style URI /weblogs/4/delete, because HTTP's uniform interface already knows about deleting. RESTFUL Web Services pg. 173 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

These two resources, a list and an item in the list, show up all the time. Every database table is a list that contains items. Anything that can be represented as an RSS or Atom feed is a list that contains items. Rails defines a RESTful architecture that makes a simplifying assumption: every resource you expose can be made to fit one of these two patterns. This makes things easy most of the time, but the cost is aggravation when you try to use Rails controllers to expose resources that don't fit this simple model.
RESTFUL Web Services pg. 173 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

RESTFUL Web Services pg. 174 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

Its almost a matter of software religion: Which is better as a URI?


www.UltraDedup.com/Videos/myvideo www.UltraDedup.com/Videos?video=myvideo

Which form of URI is better?

Best practices suggests www.UltraDedup.com/Videos/myvideo is better. Use the hierarchy form when a hierarchy is indicated.

Use the query variable form when a pattern is indicated. E.g.


www.UltraDedup.com/Videos?sizegt=50K

See suggestions in RESTFUL Web Services on page 118

HTML XML JSON JPEG etc.

<?xml version="1.0" encoding="UTF-8"?> <Person> <groups> <DeRailed>Denver Rails Group</DeRailed> </groups> <PersonalityType> Great guy! </PersonalityType> </Person>

<!DOCTYPE html>
<html> <head><script type="text/javascript">var NREUMQ=NREUMQ||[];NREUMQ.push(["mark","firstbyte",new Date().getTime()]);</script> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="author" content="Confreaks, LLC" /> <meta name="keywords" content="seminar, workshop, conference, video, conferencing, recording, record, network, powerpoint, presentation, keynote, speech, talk, lecture"/> . . .

The Uniform Interface All across the Web, there are only a few basic things you can do to a resource. HTTP provides four basic methods for the four most common operations:

Retrieve a representation of a resource: HTTP GET


Create a new resource: HTTP PUT to a new URI. or HTTP POST to an existing URI (see the "POST" section below) Modify an existing resource HTTP PUT to an existing URI Delete an existing resource: HTTP DELETE

I'll explain how these four are used to represent just about any operation you can think of. I'll also cover two HTTP methods for two less common operations: HEAD and OPTIONS.
RESTFUL Web Services pg. 97 Leonard Richardson & Sam Ruby

Resource

Resource Identifiers
Statelessness

Safety
Idempotency

I don't use HTTP request headers very often. I think it's best if the client can tweak the representation by tweaking the URI to the resource, rather than tweaking the request headers. But there is one set of headers that I think ought to be built into every HTTP client, every web service, and every service hacker's brain: the ones that make conditional GET possible.
RESTFUL Web Services pg. 138 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

Conditional HTTP GET saves client and server time and bandwidth.

It's implemented with

two response headers Last-Modified ETag two request headers If-Modified-Since Tf-None-Match
RESTFUL Web Services pg. 138 Leonard Richardson & Sam Ruby Copyright 2007 OReilley Media Inc. 978-0-596-52926-0

The difference between PUT and POST is this:

The client uses PUT when it's in charge of deciding which URI the new resource should have. The client uses POST when the server is in charge of deciding which URI the new resource should have.
RESTFUL Web Services pg. 99 Leonard Richardson & Sam Ruby

The POST method is a way of creating a new resource without the client having to know its exact URI. In most cases the client only needs to know the URI of a parent or "factory" resource. The server takes the representation from the entitybody and use it to create a new resource "underneath the "parent" resource (the meaning of "underneath" depends on context). The response to this sort of POST request usually has an HTTP status code of 201 ("Created"). Its Location header contains the URI of the newly created subordinate resource. Now that the resource actually exists and the client knows its URI, future requests can use the PUT method to modify that resource, GET to fetch a representation of it. and DELETE to delete it
RESTFUL Web Services pg. 100 Leonard Richardson & Sam Ruby

Analogy:

PUT: tell a file system to create /MyDir/MySubdir/MyFileName.txt

POST: tell a file system to create a file in /MyDir/MySubdir/ and return to the client the name the file system created.

It makes the code clearer and less brittle: Compare to GOTO-less programming. Ruby doesnt even have a native GOTO!

IF every website conformed to REST


then the WEB could be made to run faster.

Its a big

IF.

REST is prescriptive and not descriptive. Rest says how programmers should use the various HTTP 1.1 verbs but not how programmers actually use the HTTP 1.1 verbs.

The most common misuse of the uniform interface is to expose unsafe operations through GET. The dei.icio.us and Flickr APIs both do this. When you GET https://api.del.icio.us/posts/delete, you're not fetching a representation: youre modifying the dei.icio.us data set.
RESTFUL Web Services pg. 103 Leonard Richardson & Sam Ruby

Why is this bad? Well, here's a story. In 2005 Google released a client-side caching tool called Web Accelerator. It runs in conjunction with your web browser and pre-fetch-es the pages linked to from whatever page you're viewing. If you happen to click one of those links, the page on the other side will load faster, because your computer has already fetched it. Web Accelerator was a disaster. Not

because of any problem in the software itself, but because the Web is full of applications that misuse GET. Web
Accelerator assumed that GET operations were safe, that clients could make them ahead of time just in case a human being wanted to see the corresponding representations. But when it made those GET requests to real URIs, it changed the data sets. People

lost data.
RESTFUL Web Services pg. 103 Leonard Richardson & Sam Ruby

Shnelvars warning: There is no REST police on the WEB. There is no enforcement mechanism.

Shnelvars prescription regarding REST:

Make your website RESTful but dont assume anyone elses will be.

REST helps you organize your interaction with the WEB and will help future maintainers (you?) understand the interaction.

REST deals with the meta interactions between your application and the WEB. You will still have to program the details of the representation and you will often have to publish (in human readable terms) what the representation means.

Вам также может понравиться