a need for rest - Łukasz piestrzeniewicz

50
A Need for REST Łukasz ‘Bragi’ Piestrzeniewicz [email protected]

Upload: bragi

Post on 15-May-2015

1.461 views

Category:

Business


0 download

DESCRIPTION

RuPy 2008 presentation about the basics of REST architecture

TRANSCRIPT

Page 1: A Need For Rest  - Łukasz Piestrzeniewicz

A Need for RESTŁukasz ‘Bragi’ Piestrzeniewicz

[email protected]

Page 2: A Need For Rest  - Łukasz Piestrzeniewicz

Briefly About Menot so interesting details

Page 3: A Need For Rest  - Łukasz Piestrzeniewicz

REST Belongs to RuPy

Page 4: A Need For Rest  - Łukasz Piestrzeniewicz

A Need for REST

• thinking about resources

• resources vs RPC

• REST in Rails

• plain old Ruby and REST

Page 5: A Need For Rest  - Łukasz Piestrzeniewicz

REST Is Architecture

• Architecture not standard

• Rather old one

• Simple

• NOT easy

• Applicable anywhere but let’s stick to HTTP

Page 6: A Need For Rest  - Łukasz Piestrzeniewicz

Road To Resources

Access URL

• Send a file

• Run a script

• Use controller and action

Page 7: A Need For Rest  - Łukasz Piestrzeniewicz

REST Is About Resources

• Resources are named things

• Nouns

• User, Transaction, Page, Invoice

• Collections also: Users, Transactions

Page 8: A Need For Rest  - Łukasz Piestrzeniewicz

Dog

• Id

• Name

• Breed

• Color

• Mood

10001

Burek

Mongrel

Yellowish

Blue

Page 9: A Need For Rest  - Łukasz Piestrzeniewicz

Resources Have Names

URL

• Identifies resource globally

Page 10: A Need For Rest  - Łukasz Piestrzeniewicz

Collection of Dogs

http://example.com/dogs

Page 11: A Need For Rest  - Łukasz Piestrzeniewicz

Dog Named Globally

http://example.com/dogs/10001

Page 12: A Need For Rest  - Łukasz Piestrzeniewicz

Representations

• What client receives

• Use existing MIME formats

• HTML, RSS, JSON, YAML, PDF, JPG

• Bake your own

• XML flavors

Page 13: A Need For Rest  - Łukasz Piestrzeniewicz

Negotiation

• Developer decides what representations to support

• Server send one representation by default

• Client can choose specific representation

Page 14: A Need For Rest  - Łukasz Piestrzeniewicz

Dog, JSON

Accept: application/json

{ “id”: “10001”, “name”: “Burek”, “breed”: “Mongrel”, “color”: “Yellowish”, “mood”: “Blue”}

Page 15: A Need For Rest  - Łukasz Piestrzeniewicz

Dog, Picture

Accept: image/jpeg

Page 16: A Need For Rest  - Łukasz Piestrzeniewicz

Dog, Text

Accept: text/plain

, |`-.__ / ' _/ ****` / } / \ / \ /` \\\ `\ /_\\ jgs `~~~~~``~`

Page 17: A Need For Rest  - Łukasz Piestrzeniewicz

Links

• Resource knows other resources

• Especially true in case of collections

• Some representations link better than other

Page 18: A Need For Rest  - Łukasz Piestrzeniewicz

Limited Set of Actions

• Well defined verbs

• Limited to:

• GET

• POST

• PUT

• DELETE

Page 19: A Need For Rest  - Łukasz Piestrzeniewicz

Read

GET /dogs/10001

• tell what type of content you like

• cached

Page 20: A Need For Rest  - Łukasz Piestrzeniewicz

Create

• POST /dogs

• provide some meaningful data

• collection as factory

• agree on format in advance

• link in response

Page 21: A Need For Rest  - Łukasz Piestrzeniewicz

Update

PUT /dogs/10001

• give some meaningful data

• again agree in advance for data format

Page 22: A Need For Rest  - Łukasz Piestrzeniewicz

Delete

DELETE /dogs/10001

• it’s request only

• server can do what it wants to do

• no-one will delete Burek

Page 23: A Need For Rest  - Łukasz Piestrzeniewicz
Page 24: A Need For Rest  - Łukasz Piestrzeniewicz

My Browser Is Broken

• Forms support only POST and GET (abomination!)

• Simulate!

<input type=’hidden’ name=’_method’ value=’put’ />

Page 25: A Need For Rest  - Łukasz Piestrzeniewicz

StatelessTHE RULE

Page 26: A Need For Rest  - Łukasz Piestrzeniewicz

Client Keeps State

• Each request is separate

• Gets all the data

• Updates all (most of the time)

• Sessions are bad

• Cookies are bad

Page 27: A Need For Rest  - Łukasz Piestrzeniewicz
Page 28: A Need For Rest  - Łukasz Piestrzeniewicz

Let’s Recap

Resources have:

• names (URLs)

• representations

• limited set of actions

• stateless interaction

Page 29: A Need For Rest  - Łukasz Piestrzeniewicz

Advantages

• Simple clients

• Uniform access

• Scalability

Page 30: A Need For Rest  - Łukasz Piestrzeniewicz

How About RPC?

• Different philosophy

• Originated from local function call

• Action oriented

Page 31: A Need For Rest  - Łukasz Piestrzeniewicz

Entry Point

REST

• Single URL per resource

RPC

• Single URL per service

Page 32: A Need For Rest  - Łukasz Piestrzeniewicz

Message Content

REST

• Any of negotiated MIME types

RPC

• Text

• Verbose serialization format

Page 33: A Need For Rest  - Łukasz Piestrzeniewicz

HTTP Usage

REST

• Base

RPC

• Wire protocol

Page 34: A Need For Rest  - Łukasz Piestrzeniewicz

REST Vs. RPC

• Simple server

• Scales easily

• Lower bandwidth

• Lower CPU usage

Page 35: A Need For Rest  - Łukasz Piestrzeniewicz

RESTful Rails

• Out of the box in 2.0

• Both server and client side

Page 36: A Need For Rest  - Łukasz Piestrzeniewicz

Rails REST Server

Simple resource declaration

• map.resources :dogs

• DogsController

• automatic method mapping

• own methods

Page 37: A Need For Rest  - Łukasz Piestrzeniewicz

Rails REST Server

Multiple representation support

• respond_to

Page 38: A Need For Rest  - Łukasz Piestrzeniewicz

Rails REST Server

Resource name support

• URL and form helpers

• dogs_path

• dog_path(@dog)

• form_for(@dog)

• _method field trick

Page 39: A Need For Rest  - Łukasz Piestrzeniewicz

Rails REST Server

• Start with a scaffold and follow

Page 40: A Need For Rest  - Łukasz Piestrzeniewicz

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

Page 41: A Need For Rest  - Łukasz Piestrzeniewicz

What Do We Get?

• Clean architecture

• API for free

• Low bandwidth

• High scalability

Page 42: A Need For Rest  - Łukasz Piestrzeniewicz

I CAN HAS REST?

Page 43: A Need For Rest  - Łukasz Piestrzeniewicz

Questions?

Page 44: A Need For Rest  - Łukasz Piestrzeniewicz

Thank YouŁukasz ‘Bragi’ Piestrzeniewicz

[email protected]

Want to work with REST on Rails? [email protected]

Page 46: A Need For Rest  - Łukasz Piestrzeniewicz

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 

Page 47: A Need For Rest  - Łukasz Piestrzeniewicz

Google Blogger APIPerfect Example

Page 48: A Need For Rest  - Łukasz Piestrzeniewicz

Google Blogger API

• Migrated from XML-RPC to REST (Atom)

Page 49: A Need For Rest  - Łukasz Piestrzeniewicz

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>

Page 50: A Need For Rest  - Łukasz Piestrzeniewicz

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>