Download - A Need For Rest - Łukasz Piestrzeniewicz
A Need for RESTŁukasz ‘Bragi’ Piestrzeniewicz
Briefly About Menot so interesting details
REST Belongs to RuPy
A Need for REST
• thinking about resources
• resources vs RPC
• REST in Rails
• plain old Ruby and REST
REST Is Architecture
• Architecture not standard
• Rather old one
• Simple
• NOT easy
• Applicable anywhere but let’s stick to HTTP
Road To Resources
Access URL
• Send a file
• Run a script
• Use controller and action
REST Is About Resources
• Resources are named things
• Nouns
• User, Transaction, Page, Invoice
• Collections also: Users, Transactions
Dog
• Id
• Name
• Breed
• Color
• Mood
10001
Burek
Mongrel
Yellowish
Blue
Resources Have Names
URL
• Identifies resource globally
Collection of Dogs
http://example.com/dogs
Dog Named Globally
http://example.com/dogs/10001
Representations
• What client receives
• Use existing MIME formats
• HTML, RSS, JSON, YAML, PDF, JPG
• Bake your own
• XML flavors
Negotiation
• Developer decides what representations to support
• Server send one representation by default
• Client can choose specific representation
Dog, JSON
Accept: application/json
{ “id”: “10001”, “name”: “Burek”, “breed”: “Mongrel”, “color”: “Yellowish”, “mood”: “Blue”}
Dog, Picture
Accept: image/jpeg
Dog, Text
Accept: text/plain
, |`-.__ / ' _/ ****` / } / \ / \ /` \\\ `\ /_\\ jgs `~~~~~``~`
Links
• Resource knows other resources
• Especially true in case of collections
• Some representations link better than other
Limited Set of Actions
• Well defined verbs
• Limited to:
• GET
• POST
• PUT
• DELETE
Read
GET /dogs/10001
• tell what type of content you like
• cached
Create
• POST /dogs
• provide some meaningful data
• collection as factory
• agree on format in advance
• link in response
Update
PUT /dogs/10001
• give some meaningful data
• again agree in advance for data format
Delete
DELETE /dogs/10001
• it’s request only
• server can do what it wants to do
• no-one will delete Burek
My Browser Is Broken
• Forms support only POST and GET (abomination!)
• Simulate!
<input type=’hidden’ name=’_method’ value=’put’ />
StatelessTHE RULE
Client Keeps State
• Each request is separate
• Gets all the data
• Updates all (most of the time)
• Sessions are bad
• Cookies are bad
Let’s Recap
Resources have:
• names (URLs)
• representations
• limited set of actions
• stateless interaction
Advantages
• Simple clients
• Uniform access
• Scalability
How About RPC?
• Different philosophy
• Originated from local function call
• Action oriented
Entry Point
REST
• Single URL per resource
RPC
• Single URL per service
Message Content
REST
• Any of negotiated MIME types
RPC
• Text
• Verbose serialization format
HTTP Usage
REST
• Base
RPC
• Wire protocol
REST Vs. RPC
• Simple server
• Scales easily
• Lower bandwidth
• Lower CPU usage
RESTful Rails
• Out of the box in 2.0
• Both server and client side
Rails REST Server
Simple resource declaration
• map.resources :dogs
• DogsController
• automatic method mapping
• own methods
Rails REST Server
Multiple representation support
• respond_to
Rails REST Server
Resource name support
• URL and form helpers
• dogs_path
• dog_path(@dog)
• form_for(@dog)
• _method field trick
Rails REST Server
• Start with a scaffold and follow
ActiveResource
• Client counterpart
• Easy to set-up
require "activeresource/lib/active_resource" class Dog < ActiveResource::Base self.site = "http://example.com" end
dog = Dog.find(10001)dog.mood = "cheerful"dog.save
What Do We Get?
• Clean architecture
• API for free
• Low bandwidth
• High scalability
I CAN HAS REST?
Questions?
Thank YouŁukasz ‘Bragi’ Piestrzeniewicz
Want to work with REST on Rails? [email protected]
Useful Links
• REST wikihttp://REST.blueoxen.net/
• Original Roy Fielding Presentationhttp://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
• The REST Dialogueshttp://duncan-cragg.org/blog/post/getting-data-REST-dialogues/
The Simplest Client
• Stolen from Twitter API
• Get the public timeline, unauthenticated:curl http://twitter.com/statuses/public_timeline.rss
• Get your friends timeline, authenticated:curl -u email:password http://twitter.com/statuses/friends_timeline.xml
• Just the headers, please:curl --head -u email:password http://twitter.com/statuses/friends_timeline.json
• Post a status update, authenticated:curl -u email:password -d status="your message here" http://twitter.com/statuses/update.xml
Google Blogger APIPerfect Example
Google Blogger API
• Migrated from XML-RPC to REST (Atom)
Listing User Blogs, RPCPOST /api/RPC2 HTTP/1.0User-Agent: Java.Net Wa-Wa 2.0Host: plant.blogger.comContent-Type: text/xmlContent-length: 515
<?xml version="1.0"?><methodCall> <methodName>blogger.getUsersBlogs</methodName> <params> <param><value><string>C6CE3FFB3174106584CBB250C0B0519BF4E294</string></value></param> <param><value><string>ewilliams</string></value></param> <param><value><string>secret</string></value></param> </params></methodCall>
HTTP/1.1 200 OKConnection: closeContent-Length: 125Content-Type: text/xmlDate: Mon, 6 Aug 20001 19:55:08 GMTServer: Java.Net Wa-Wa/Linux
<?xml version="1.0" encoding="ISO-8859-1"?><methodResponse> <params> <param> <value> <array> <data> <value> <struct> <member> <name>url</name> <value>http://stuff.foo.com/biz</value> </member> <member> <name>blogid</name> <value>2997323</value> </member> <member> <name>blogName</name> <value>Blogger Biz Dev</value> </member> </struct> </value> <value> <struct> <member> <name>url</name> <value>http://www.blogger.com/</value> </member> <member> <name>blogid</name> <value>2723</value> </member> <member> <name>blogName</name> <value>Blogger News</value> </member> </struct> <value> <struct> <member> <name>url</name> <value>http://www.geocities.com/rafting/</value> </member> <member> <name>blogid</name> <value>223723</value> </member> <member> <name>blogName</name> <value>RaftingBlog</value> </member> </struct> </value> </value> </data> </array> </value> </param> </params></methodResponse>
Listing User Blogs, REST
GET /feeds/userID/blogs HTTP/1.0Host: www.blogger.com
<entry> <id>tag:blogger.com,1999:user-59644548838.blog-17220805</id> <published>2007-02-16T11:58:52.809+01:00</published> <updated>2008-03-14T16:51:04.068+01:00</updated> <title type='text'>Ragnarson</title> <summary type='html'>Ragnarson</summary> <link rel='alternate' type='text/html' href='http://ragnarson.blogspot.com/' /> <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ragnarson.blogspot.com/feeds/posts/default' /> <link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='http://www.blogger.com/feeds/17220805/posts/default' /> <link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12109437004322472888/blogs/17220805' /> <author> <name>Bragi</name> </author> </entry>