RESTful best practices

44
RESTful best practices Jean-Baptiste Escoyez & Nicolas Jacobeus FOSDEM ’08 Ruby on Rails DevRoom 24 February 2008 Frailers.net

description

Best practices when designing a RESTful web application. Presented at the Ruby and Rails devroom at FOSDEM 2008.

Transcript of RESTful best practices

Page 1: RESTful best practices

RESTful best practicesJean-Baptiste Escoyez & Nicolas Jacobeus

FOSDEM ’08 Ruby on Rails DevRoom24 February 2008

Frailers.net

Page 2: RESTful best practices

Outline

REST

REST in Rails

REST in Rails: Best practices

Page 3: RESTful best practices

REST

Page 4: RESTful best practices

REST

What is REST?

How does REST work?

Why REST?

REST

Page 5: RESTful best practices

What is REST?

It’s about communication between computers

It’s about designing the architecture of your applications

REST » What is REST?

Page 6: RESTful best practices

It’s about communication between computers

Web services!

SOAP / XML-RPC => communication

REST => communication + standardisation

REST » What is REST?

Page 7: RESTful best practices

It’s about architecturing your application

esis by Roy Fielding (2000)“Architectural Styles and the Design of Network-based Software Architectures”

REST applies some constraints to the architecture of your application

e interface is the same for humans and computers

(by the way: REST means Representational State Transfer... I think)‏

REST » What is REST?

Page 8: RESTful best practices

How does REST work ?

Everything is a “resource”

4 basic requirements for a RESTful system

REST » How does REST work?

Page 9: RESTful best practices

e concept of resource

Resource = thing exposed by the system to the outside world

Everything is a resourcehttp://www.frailers.net/users/1http://www.frailers.net/users/1/memberships

Independent from its representationuser.html => http://www.frailers.net/users/1user.jpg => http://www.frailers.net/users/1

REST » How does REST work?

Page 10: RESTful best practices

When is a system RESTful ?

Addressability

Statelessness

Connectivity

Uniform interface

4 standardized actions: GET - POST - PUT - DELETE

Safety (GET)

Idempotence (PUT-DELETE)

REST » How does REST work?

Page 11: RESTful best practices

So, why REST ?

Standardisation is good

Why use so many different functions when you always do the same (CRUD’ing objects)

Why separate the logic for computers and humans ? (segregation is evil)

Statelessness => scalability and decoupling

REST » Why REST?

Page 12: RESTful best practices

Enough for this theoretical HTTP stuff!

is is a DevRoom about , right ?

REST » Why REST?

Page 13: RESTful best practices

REST in Rails

(Not on Rails !)

Page 14: RESTful best practices

REST in Rails

Addressability: RESTful routes

Representation independence: respond_to

Nesting resources

Developing REST clients

...and some tasty Rails sugars

REST in Rails

Page 15: RESTful best practices

Addressability : Routes

REST in Rails » Routes

RESTless RESTfulVERB HREF VERB URIPOST /users/create POST /users

GET /users/1 GET /users/1

POST /users/1/update PUT /users/1

???? /users/1/delete DELETE /users/1

Page 16: RESTful best practices

Addressability : Routes

REST in Rails » Routes

map.resources :usersResource Verb Action

/users GET index/users POST create

/users/1 GET show/users/1 PUT update/users/1 DELETE destroy

Page 17: RESTful best practices

RESTful Rails controller

A RESTful controller has 7 standard actions

Each controller deals with a resource (user) and its collection (list of users)

REST in Rails » Routes

Page 18: RESTful best practices

Representation independence: respond_to

Based on:

HTTP Accept Header

Format extensionhttp://www.frailers.net/articles/24/comments/1.htmlhttp://www.frailers.net/articles/24/comments/1.js

REST in Rails » respond_to

Page 19: RESTful best practices

Making REST clients : ActiveResource

class Project < ActiveResource::Base self.site = “http://localhost:3000”end

projects = Project.find(:all)new_project = Project.new(:name => “My new project”)new_project.save

REST in Rails » ActiveResource

Page 20: RESTful best practices

Nested resourceshttp://www.frailers.net/articles/24/comments/1http://www.frailers.net/articles/24/author

ActionController::Routing::Routes.draw do |map| map.resources :articles do |article| article.resources :comments article.resource :author endend

REST in Rails » Nested resources

Page 21: RESTful best practices

More rails sugars

Scaffolding

script/generate scaffold article title:string \ body:text published:boolean

Helperslink_to @articleform_for @comment do |f| ... endredirect_to @article

AuthenticationRESTful authentication plugin

REST in Rails » Sugars

Page 22: RESTful best practices

To sum up...

Using REST in Rails is good

lightweight controllers

API given for free

Rails is opinionated

implementation of REST is not perfect

REST in Rails » Conclusion

Page 23: RESTful best practices

Best practices

Page 24: RESTful best practices

Best practices

Design methodology

Real-life examples

Best Practices

Page 25: RESTful best practices

Disclaimer!

Maybe “best” is an overstatement(is sounded great for the call for papers)

ere are always different solutions

Best Practices » Disclaimer

Page 26: RESTful best practices

Design methodology

Knowing Rails’ resources API is great, but not sufficient

e big question:

what resources do I choose ?

Best Practices » Design methodology

Page 27: RESTful best practices

Classic beginner’s mistakes

strictly mirroring your ActiveRecord data model to choose your resources

thinking all 7 actions should be written for each and every resource

and, of course, adding custom methods if the standard ones don’t fit

Best Practices » Design methodology

Page 28: RESTful best practices

Resources are not models

Well, to be fair, then can (and usually) represent models

But also:RelationsStatesEvents(DHH told me so)

Best Practices » Design methodology

Page 29: RESTful best practices

Nouns are the new verbs

Change your way of explaining a scenario, an action

Use a noun to describe the action

e noun given to your scenario is the resource you’re looking for

A user subscribes to a group A subscription is created

e project is validated by its owner A project validation is created

e user deactivates his account A user account activation is deleted

Best Practices » Design methodology

Page 30: RESTful best practices

7 is not a strict target

Resources can be read-only

Sometimes, actions aremeaningless:

update an “account activation” ? really ?

destroy a “page view” ? why ?

Best Practices » Design methodology

Page 31: RESTful best practices

Don’t be tempted!

Rails allows extra, custom methods to be added to controllers, if you really need them

But you’ll lose all what you were trying to do in the first place (no uniform interface, etc.)

I have never needed that (except, maybe...)

If you do need that, it’s probable that you’d better rethink your architecture

Best Practices » Design methodology

Page 32: RESTful best practices

OK, you want real-life examples

Adding/removing members from a group

Dealing with object workflows

Multi-step edition wizard

Managing a shopping cart

Manipulating several resource in one request

Best Practices » Real-life examples

Page 33: RESTful best practices

Adding / Removing members from a group

Best Practices » Real-life examples

Page 34: RESTful best practices

Adding / Removing members from a group

Best Practices » Real-life examples

Page 35: RESTful best practices

Dealing with object workflows

Consider a CMS withall sorts of documents

Each document has a status: draft, reviewed,published, ...

Best Practices » Real-life examples

Page 36: RESTful best practices

Dealing with object workflows

Or another way : only “update” the document

depending on the business logic, this can be considered overloading

Best Practices » Real-life examples

Page 37: RESTful best practices

Multi-step edition wizard

A complex model needs tobe edited in 3 steps, in aprecise order

Best Practices » Real-life examples

Page 38: RESTful best practices

Multi-step edition wizard

All these steps are different, partial representations of the same resource

Just GET the resource and put the step as a parameter

Update the resource at each step... and redirect to the next step representation

Best Practices » Real-life examples

Page 39: RESTful best practices

Multi-step edition wizard

Best Practices » Real-life examples

Page 40: RESTful best practices

Managing a shopping cart

We keep in the database the state of the shopping cart for each user:/users/21/shopping_cart_items

Yes, but I don’t want the cart to be persistentDelete from the database when the user logs out

Best Practices » Real-life examples

Page 41: RESTful best practices

Manipulating two resources simultaneously

You’re not manipulating two resources

You’re manipulating a couple of things

e resource is the couple

Create guy, create girl => Create couple

Best Practices » Real-life examples

Page 42: RESTful best practices

Manipulating two resources simultaneously

If you still need to do it inseveral steps...

CREATE a Transaction resource

PUT the first part

PUT the second part

commit (PUT “committed”)or revert (DELETE)

Best Practices » Real-life examples

Page 43: RESTful best practices

ere are still some limitations...

I want to choose items to delete from a list with checkboxes

DELETE only works for a single resource at a time

What you’re doing is updating the parent resource

If there’s no parent resource, you’re screwed

Best Practices » Real-life examples

Page 44: RESTful best practices

ank you!

It’s lunch time!

Let’s eat!

Let’s create some LunchEatings !

POST /lunch_eatings