You are on page 1of 148

Copyright 2005 John Cowan under GPL 1

RESTful We Ser!i"e#
$n introdu"tion to uilding We Ser!i"e#
without tear# %i&e&' without S($P or WS)L*
John Cowan
"owan+""il&org
http,--www&""il&org-."owan
Copyright 2005 John Cowan under GPL 2
Copyright

Copyright / 2005 John Cowan

Li"en#ed under the G01 General Puli"


Li"en#e

$2S(L1TEL3 0( W$RR$0T4ES5 1SE $T 3(1R


(W0 R4S6

2la"7 and white for readaility

Gentiu8 font for readaility and eauty


Copyright 2005 John Cowan under GPL 9
The Pit"h
Would you li7e #o8ething "leaner than S($P:
So8ething le## i8penetrale than WS)L:
So8ething le## "onfu#ingly intertwingled than
the !ariou# WS;< afflega #tandard#: &&& Say' =u#t
what i# thi# We Ser!i"e# =a>> anyhow:
Copyright 2005 John Cowan under GPL ?
The Pit"h
4t@# all 0o Prole8& 4t@# all Ea#y a# Pi& REST i#n@t
#o8e o#"ure thing that noody #upport#5 it@# the
way the We already wor7#' =u#t for8ali>ed a it
and with #o8e do@# and don@t#&
Copyright 2005 John Cowan under GPL 5
The Pit"h
2y de"on#tru"ting what you already 7now aout
the We' you "an reuild it into a #et of prin"iple#
for #ound de#ign' without worrying aout it& 0o'
it won@t e Ayou pu#h the utton' we do the
RESTB& 2ut it@ll e "lean' #e"ure' #traightforward'
eCten#ile' di#"o!erale' 8aintainale&
Copyright 2005 John Cowan under GPL D
Tal7 i# "heap
2ut thatE# what youEre going to get today& $fter
weEre done here' go ho8e and try it for your#elf&
Copyright 2005 John Cowan under GPL F
1nifor8 Re#our"e 4dentifier

4 u#e the ter8 A1R4B %1nifor8 Re#our"e


4dentifier* throughout

4f it 8a7e# you feel etter' "ro## it out and u#e


A1RLB in#tead

Contrary to all propaganda' there are no


effe"ti!e differen"e# the#e day#
Copyright 2005 John Cowan under GPL G
Credit#

The gut# of thi# pre#entation "o8e# fro8 the


writing# of,

Roy Hielding

Ryan To8ay7o

Paul Pre#"od

Iar7 2a7er

Jeff 2one (conversus)

$ll the "ontriutor# to Re#tWi7i


Copyright 2005 John Cowan under GPL J
Road8ap

We Ser!i"e# %12*

What@# REST: %1G*

The 7iller argu8ent %F*

)i#triuted Sy#te8# %19*

What aout &&& %19*

Clarifying A#tateB %D*

Hro8 here to there %1G*

S($P %J*

Cleaning up %1?*

RESTafarian e8ail %G*

Related ar"hite"ture# %D*

Hinal thought# %9*


Copyright 2005 John Cowan under GPL 10
We Ser!i"e#
Copyright 2005 John Cowan under GPL 11
What@# a We Ser!i"e:

$ we #er!i"e i# =u#t a we page 8eant for a


"o8puter to reKue#t and pro"e##

Iore pre"i#ely' a We #er!i"e i# a We page


that@# 8eant to e "on#u8ed y an autonomous
progra8 a# oppo#ed to a We row#er or
#i8ilar 14 tool
Copyright 2005 John Cowan under GPL 12
What@# a We Ser!i"e:

We Ser!i"e# reKuire an ar"hite"tural #tyle to


8a7e #en#e of the8' e"au#e there@# no #8art
hu8an eing on the "lient end to 7eep tra"7

The pre;We te"hniKue# of "o8puter


intera"tion donEt #"ale on the 4nternet

They were de#igned for #8all #"ale# and #ingle


tru#t do8ain#
Copyright 2005 John Cowan under GPL 19
The #"ope of the prole8

Co8puter $ in 0ew 3or7 &&&

&&& tell# "o8puter 2 in Sa8ar7and &&&

&&& aout a re#our"e a!ailale on Co8puter C in


Ti8u7tu

0one of the8 elong# to the #a8e tru#t


do8ain
Copyright 2005 John Cowan under GPL 1?
0oun#

1R4# are the eKui!alent of a noun

Io#t word# in Engli#h are noun#' fro8 cat to


antidisestablishmentarianism

The REST language ha# trillion# of noun# for all


the "on"ept# in all the head# and file# of all the
people in the world
Copyright 2005 John Cowan under GPL 15
Ler#

Ler# %loo#ely* de#"rie a"tion# that are


appli"ale to noun#

1#ing different !er# for e!ery noun would


8a7e wide#pread "o88uni"ation i8po##ile

4n progra88ing we "all thi# Apoly8orphi#8B

So8e !er# only apply to a few noun#

4n REST we u#e universal !er# only


Copyright 2005 John Cowan under GPL 1D
GET, fet"h infor8ation

To fet"h a we page' the row#er doe# a GET


on #o8e 1R4 and retrie!e# a repre#entation
%MTIL' plain teCt' JPEG' or whate!er* of the
re#our"e identified y that 1R4

GET i# funda8ental to row#er# e"au#e


8o#tly they =u#t row#e

REST reKuire# a few 8ore !er# to allow ta7ing


a"tion#
Copyright 2005 John Cowan under GPL 1F
Hour !er# for e!ery noun

GET to retrie!e infor8ation

P(ST to add new infor8ation' #howing it#


relation to old infor8ation

P1T to update infor8ation

)ELETE to di#"ard infor8ation


Copyright 2005 John Cowan under GPL 1G
0ot #u"h a ig deal

The We already #upport# 8a"hine;to;


8a"hine integration

WhatE# not 8a"hine;pro"e##ale aout the


"urrent We i#nEt the proto"ol' itE# the content
Copyright 2005 John Cowan under GPL 1J
NIL

1#ing NIL for8at# a# your 8a"hine;


pro"e##ale repre#entation# for re#our"e#
allow# applying new tool# to old data

4t al#o #i8plifie# inter"onne"tion with re8ote


#y#te8#

NIL ha# plenty of tool#' a# we all 7now


Copyright 2005 John Cowan under GPL 20
Why not =u#t u#e plain MTIL:

We page# are de#igned to e under#tood y


people' who "are aout layout and #tyling' not
=u#t raw data

E!ery 1R4 "ould ha!e a hu8an;readale and a


8a"hine;pro"e##ale repre#entation,

We Ser!i"e# "lient# a#7 for the 8a"hine;readale


one

2row#er# a#7 for the hu8an;readale one


Copyright 2005 John Cowan under GPL 21
Well' not Kuite e!ery 1R4

The infor8ation on #o8e page# i# going to e


too "o8pleC for 8a"hine# to under#tand

Anna Karenina ha# lot# of 8eaning' ut 8a7ing


it into a non;tri!ial We #er!i"e i# an $4;
"o8plete prole8
Copyright 2005 John Cowan under GPL 22
$re we doing thi# now:

Io#t of u# are are u#y writing to layer# of


"o8pleC #pe"ifi"ation#

(ur noun# arenEt uni!er#al

(ur !er# arenEt poly8orphi"

The pro!en te"hniKue# of the We are eing


di#"arded for a pot of 8e##age#
Copyright 2005 John Cowan under GPL 29
What@# REST:
Copyright 2005 John Cowan under GPL 2?
So whatE# REST already:

REpre#entational State Tran#fer

$n ar"hite"tural #tyle' not a tool7it

AWe donEt need no #teen7inE tool7it#OB

$ di#tillation of the way the We already


wor7#
Copyright 2005 John Cowan under GPL 25
REST defined

Re#our"e# are identified y unifor8 re#our"e


identifier# %1R4#*

Re#our"e# are 8anipulated through their


repre#entation#

Ie##age# are #elf;de#"ripti!e and #tatele##

Iultiple repre#entation# are a""epted or #ent

MyperteCt i# the engine of appli"ation #tate


Copyright 2005 John Cowan under GPL 2D
REST #tyle

Client;#er!er

Statele##

Ca"hed

1nifor8 interfa"e

Layered #y#te8

%Code on de8and*
Copyright 2005 John Cowan under GPL 2F
Snar7y Kue#tion

Mow are repre#entation# tran#ferred' and why


would 4 want a repre#entation of #o8ething to
e tran#ferred to #o8ething el#e:

Repre#entation# are all we really ha!e %the


#hadow# in PlatoE# "a!e*

Repre#entation# are tran#ferred y ordinary


digital 8ean# P itE# how we thin7 aout the8
thatE# new
Copyright 2005 John Cowan under GPL 2G
Repre#entation

Re#our"e# are fir#t;"la## o=e"t#

4ndeed' Ao=e"tB i# a #utype of Are#our"eB

Re#our"e# are retrie!ed not a# "hara"ter


#tring# or 2L(2# ut a# "o8plete
repre#entation#
Copyright 2005 John Cowan under GPL 2J
$ we page i# a re#our"e:

$ we page i# a representation of a re#our"e

Re#our"e# are =u#t "on"ept#

1R4# tell a "lient that thereE# a "on"ept


#o8ewhere

Client# "an then reKue#t a #pe"ifi"


repre#entation of the "on"ept fro8 the
repre#entation# the #er!er 8a7e# a!ailale
Copyright 2005 John Cowan under GPL 90
State

AStateB 8ean# appli"ation-#e##ion #tate

Iaintained a# part of the "ontent tran#ferred


fro8 "lient to #er!er a"7 to "lient

Thu# any #er!er "an potentially "ontinue


tran#a"tion fro8 the point where it wa# left
off

State i# ne!er left in li8o


Copyright 2005 John Cowan under GPL 91
Tran#fer of #tate

Conne"tor# %"lient' #er!er' "a"he' re#ol!er'


tunnel* are unrelated to #e##ion#

State i# 8aintained y eing tran#ferred fro8


"lient# to #er!er# and a"7 to "lient#
Copyright 2005 John Cowan under GPL 92
REST and MTTP

REST i# a post hoc de#"ription of the We

MTTP 1&1 wa# de#igned to "onfor8 to REST

4t# 8ethod# are defined well enough to get


wor7 done

1n#urpri#ingly' MTTP i# the 8o#t RESTful


proto"ol

2ut itE# po##ile to apply REST "on"ept# to


other proto"ol# and #y#te8#
Copyright 2005 John Cowan under GPL 99
(ther proto"ol#

We intera"tion u#ing other proto"ol# i#


re#tri"ted to REST #e8anti"#

Sa"rifi"e# #o8e of the ad!antage# of other


ar"hite"ture#

Stateful intera"tion with an HTP #ite

Rele!an"e feeda"7 with W$4S #ear"h

Retain# a #ingle interfa"e for e!erything


Copyright 2005 John Cowan under GPL 9?
ECi#ting MTTP u#e#

We row#ing %o!iou#ly*

4n#tant 8e##aging

Content 8anage8ent

2logging %with $to8*

WhatE# out#ide it# #"ope:


Copyright 2005 John Cowan under GPL 95
What do REST 8e##age# loo7 li7e:

Li7e what we already 7now, MTTP' 1R4#' et"&

REST "an #upport any 8edia type' ut NIL i#


eCpe"ted to e the 8o#t popular tran#port for
#tru"tured infor8ation&

1nli7e S($P and NIL;RPC' REST doe# not


really reKuire a new 8e##age for8at
Copyright 2005 John Cowan under GPL 9D
Iultiple repre#entation#

Io#t re#our"e# ha!e only a #ingle


repre#entation

NIL 8a7e# it po##ile to ha!e a# 8any


repre#entation# a# you need

3ou "an e!en !iew the8 in a "le!er way'


than7# to the 8agi" of NSLT and CSS
Copyright 2005 John Cowan under GPL 9F
Why hyperteCt:

2e"au#e the lin7# 8irror the #tru"ture of how


a u#er 8a7e# progre## through an appli"ation

The u#er i# in "ontrol' than7# to the 2a"7


utton and other non;lo"al a"tion#

4n a We #er!i"e' the "lient #hould e in


"ontrol in the #a8e #en#e
Copyright 2005 John Cowan under GPL 9G
We;a#ed appli"ation#

$ We;a#ed appli"ation i# a dyna8i"ally


"hanging graph of

#tate repre#entation# %page#*

potential tran#ition# %lin7#* etween #tate#

4f it doe#n@t wor7 li7e that' it 8ay e accessible


fro8 the We' ut it@# not really part of the
We
Copyright 2005 John Cowan under GPL 9J
Code on de8and

Ja!a applet# weren@t #o hot

Ja!a#"ript i# !ery hot

The N8lMttpReKue#t o=e"t let# you do REST


fro8 inside a we page

Io#t row#er# pro!ide it nowaday#' with a few


annoying differen"e#

4t doe#n@t really reKuire NIL 8e##age#


Copyright 2005 John Cowan under GPL ?0
$ few #i8ple te#t# of RESTfulne##

Can 4 do a GET on the 1RL# that 4 P(ST to:

4ff #o' do 4 get #o8ething that in #o8e way


repre#ent# the #tate of what 4E!e een uilding
up with the P(ST#:

MTIL for8# al8o#t alway# fail 8i#eraly


Copyright 2005 John Cowan under GPL ?1
$ few #i8ple te#t# of RESTfulne##

Would the "lient noti"e if the #er!er were to e

re#tarted at any point etween reKue#t#

re;initiali>ed y the ti8e the "lient 8ade the neCt


reKue#t

The#e te#t# are not anything li7e "o8plete


Copyright 2005 John Cowan under GPL ?2
The 7iller argu8ent
Copyright 2005 John Cowan under GPL ?9
$rgu8ent# again#t non;REST de#ign#

They rea7 We ar"hite"ture' parti"ularly


"a"hing

They donEt #"ale well

They ha!e #ignifi"antly higher "oordination


"o#t#
Copyright 2005 John Cowan under GPL ??
Ca"hing: Well &&&

The WeE# "a"hing ar"hite"ture of the We


i#nEt alway# the Right Thing

1#ing P(ST loo#ely to 8ean AdonEt "a"heB ha#


een a good way of dealing with thi# prole8

Learning the #tri"ter REST #e8anti"# of P(ST


i#nEt =u#t an eCten#ion of eCi#ting pra"ti"e
Copyright 2005 John Cowan under GPL ?5
S"aling: Well&&&

What 7ind of #"aling i# 8o#t i8portant i#


appli"ation;#pe"ifi"

0ot all app# are Mot8ail' Google' or $8a>on

4ntegration etween two "orporate app# ha#


different #"aling and a!ailaility need#

The right approa"h to one i#nEt ne"e##arily the


right approa"h to the other
Copyright 2005 John Cowan under GPL ?D
The 7iller argu8ent

$ #er!i"e offered in a REST #tyle will


inherently e ea#ier to "on#u8e than #o8e
"o8pleC $P4,

Lower learning "ur!e for the "on#u8er

Lower #upport o!erhead for the produ"er


Copyright 2005 John Cowan under GPL ?F
What if REST i# not enough:

What happen# when you need appli"ation


#e8anti"# that donEt fit into the GET - P1T -
P(ST - )ELETE generi" interfa"e# and
repre#entational #tate 8odel:

People tend to a##u8e that the REST an#wer i#,

4f the prole8 doe#nEt fit MTTP' uild another


proto"ol

ECtend MTTP y adding new MTTP 8ethod#


Copyright 2005 John Cowan under GPL ?G
2ut in fa"t,

There are no applications you can think of which


cannot be made to fit into the GET / PT / P!"T /
#E$ETE resources / representations model of the
world%

The#e interfa"e# are #uffi"iently general

(ther interfa"e# "on#idered har8ful e"au#e


they in"rea#e the "o#t# of "on#u8ing
parti"ular #er!i"e#
Copyright 2005 John Cowan under GPL ?J
2e fruitful and 8ultiply

REST de#ign appear# to 8a7e we app# 8ore


li7ely to "o8ine #u""e##fully with other we
app#

The re#ulting "o8pleCe# of appli"ation# ha!e a


larger effe"t on the we a# a whole

REST tend# to appear on the large#t #"ale#

We don@t 7now in ad!an"e whi"h app# will


e"o8e large;#"ale
Copyright 2005 John Cowan under GPL 50
)i#triuted Sy#te8#
Copyright 2005 John Cowan under GPL 51
)i#triuted Sy#te8#

Co8ponent# %origin #er!er#' gateway#'


proCie#' u#er agent#*

Conne"tor# %"lient#' #er!er#' "a"he#' re#ol!er#'


tunnel#*

)ata ele8ent# %re#our"e#' re#our"e identifier#'


repre#entation#*
Copyright 2005 John Cowan under GPL 52
Co8ponent#

Co88uni"ate y tran#ferring repre#entation#


of re#our"e# through a #tandard interfa"e
rather than operating dire"tly upon the
re#our"e it#elf

1#ed to a""e##' pro!ide a""e## to' or 8ediate


a""e## to re#our"e#

4nter8ediarie# are part of the ar"hite"ture' not


=u#t infra#tru"ture li7e 4P router#
Copyright 2005 John Cowan under GPL 59
So8e "o8ponent#

!ri&in servers' $pa"he' 44S

Gateways' SKuid' CG4' Re!er#e ProCy

Pro(ies' Gauntlet

ser a&ents' HirefoC' Io>illa' Safari' 4E


Copyright 2005 John Cowan under GPL 5?
Conne"tor#

Pre#ent an a#tra"t interfa"e for "o8ponent


"o88uni"ation' hiding the i8ple8entation
detail# of "o88uni"ation 8e"hani#8#

$ll reKue#t# 8u#t e #tatele##' "ontaining all


the infor8ation ne"e##ary for the
under#tanding of that reKue#t without
depending on any pre!iou# reKue#t
Copyright 2005 John Cowan under GPL 55
So8e "onne"tor#

)lients' row#er#' feedreader#' lirarie#' 8any


#pe"iali>ed appli"ation#

"ervers' $pa"he' 44S' $(L#er!er

)aches' row#er "a"he' $7a8ai "a"he networ7

*esolvers' )0S loo7up' )(4 loo7up

Tunnels' S(C6S' SSL after MTTP C(00ECT


Copyright 2005 John Cowan under GPL 5D
The "onne"tor !iew

Con"entrate# on the 8e"hani"# of the


"o88uni"ation etween "o8ponent#&

Con#train# the definition of the generi"


re#our"e interfa"e
Copyright 2005 John Cowan under GPL 5F
Re#our"e 8odeling

The !alue of "o8ponent# and "onne"tor# i#


8o#tly o!iou#

Re#our"e#' repre#entation#' 1R4#' and


#tandardi>ed interfa"e# are 8ore #utle
8atter#
Copyright 2005 John Cowan under GPL 5G
Re#our"e 8odeling

(rgani>e a di#triuted appli"ation into 1R4;


addre##ale re#our"e#

1#e only the #tandard MTTP 8e##age# ;; GET'


P1T' P(ST and )ELETE ;; to pro!ide the full
"apailitie# of that appli"ation
Copyright 2005 John Cowan under GPL 5J
So8e data ele8ent#

*esources' the intended "on"eptual target of a


hyperteCt referen"e

*esource identifiers' 1R4#

*esource metadata' #our"e lin7#' alternate#

*epresentations' MTIL do"u8ent#' JPEG i8age#

*epresentation+specific metadata' 8edia type'


la#t;8odified ti8e
Copyright 2005 John Cowan under GPL D0
$d!antage# of REST

4t# ar"hite"tural "on#traint# when applied as a


whole' generate,

S"alale "o8ponent intera"tion#

General interfa"e#

4ndependently deployed "onne"tor#

Redu"ed intera"tion laten"y

Strengthened #e"urity

Safe en"ap#ulation of lega"y #y#te8#


Copyright 2005 John Cowan under GPL D1
$d!antage# of REST

Support# inter8ediarie# %proCie# and


gateway#* a# data tran#for8ation and "a"hing
"o8ponent#

Con"entrate# the appli"ation #tate within the


u#er agent "o8ponent#' where the #urplu# di#7
and "y"le# are
Copyright 2005 John Cowan under GPL D2
$d!antage# of REST

Separate# #er!er i8ple8entation fro8 the


"lientE# per"eption of re#our"e# %ACool 1R4#
)on@t ChangeB*

S"ale# well to large nu8er# of "lient#

Enale# tran#fer of data in #trea8# of


unli8ited #i>e and type
Copyright 2005 John Cowan under GPL D9
The 7ey in#ight#

)i#"rete re#our"e# #hould e gi!en their own


#tale 1R4#

MTTP' 1R4#' and the a"tual data re#our"e#


a"Kuired fro8 1R4# are #uffi"ient to de#"rie
any "o8pleC tran#a"tion' in"luding

#e##ion #tate

authenti"ation-authori>ation
Copyright 2005 John Cowan under GPL D?
What aout &&&
Copyright 2005 John Cowan under GPL D5
GET# that wonEt fit in a 1R4

Re#tri"ting GET to a #ingle line enfor"e# a


good de#ign prin"iple that e!erything
intere#ting on the we #hould e 1R4;
addre##ale&

Changing an appli"ation to fit GETE#


li8itation# 8a7e# the appli"ation better y
8a7ing it "o8patile with the re#t of the we
ar"hite"ture
Copyright 2005 John Cowan under GPL DD
Reliaility

The We "on#i#t# of 8any redundant


re#our"e#

4t 8ight e po##ile to find an alternate


repre#entation and tran#fer the #e##ion there

)ataa#e# don@t nor8ally allow thi#

The We i# a world of "on#tantly #hifting'


redundant' o!erlapping networ7 "o8ponent#
in a wide !ariety of #tate#&
Copyright 2005 John Cowan under GPL DF
Reliaility

3ou "an do reliale deli!ery in MTTP ea#ily at


the appli"ation le!el

The guarantee# pro!ided y TCP get you pretty


far' and then you need =u#t a it 8ore

Conne"tor reliaility i# #ol!ed y redundan"y


and other #tandard 8ean# that ha!e nothing
to do with REST
Copyright 2005 John Cowan under GPL DG
Reliaility

4f at fir#t you donEt #u""eed' try' try againO

The MTTP GET' P1T and )ELETE 8ethod# are


already ide8potent' ut the P(ST 8ethod
"reate# new re#our"e#

Iultiple P(ST# of the #a8e data 8u#t e 8ade


har8le##

Put #o8e 7ind of 8e##age 4) in a header or in


the 8e##age ody
Copyright 2005 John Cowan under GPL DJ
Reliaility

Client# arenEt that good at generating truly


uniKue 8e##age 4)#

Paul Pre#"od@# #olution,

The "lient P(ST# to a 1R4 a#7ing for a uniKue


#er!er;generated 8e##age 4)

The #er!er return# an MTTP QLo"ation,Q header


pointing to a newly generated 1R4 where the
"lient 8ay P(ST the a"tual data&
Copyright 2005 John Cowan under GPL F0
Reliaility

The original P(ST i# u#ed only to generate


8e##age 4)#' whi"h are "heap&

Retire the8 %whether they ha!e een u#ed or not*


after a few hour#

(r hold on to the8 for wee7#O


Copyright 2005 John Cowan under GPL F1
Reliaility

Wa#ted 4)# are irrele!ant&

)upli"ated P(ST# are not a"ted on y the


#er!er

The #er!er 8u#t #end a"7 the #a8e re#pon#e


the original P(ST got' in "a#e the appli"ation i#
retrying e"au#e it lo#t the re#pon#e
Copyright 2005 John Cowan under GPL F2
$#yn"hronou# operation#

Send a"7 notifi"ation# a# P(ST# %the "lient


"an i8ple8ent a tri!ial MTTP #er!er*

Piggya"7 the8 on the re#pon#e# to later


reKue#t#

0o "o8plete #olution yet


Copyright 2005 John Cowan under GPL F9
Tran#a"tion#

The "lient i# ulti8ately re#pon#ile

(ther de#ign# arenEt 8u"h etter

)ataa#e;#tyle tran#a"tion# donEt #"ale well on


the We

Client# will #tart tran#a"tion# and then forget


aout the8

Tie# up #er!er re#our"e#

Lo"7# out all other u#er#


Copyright 2005 John Cowan under GPL F?
REST out#ide the We:

REST "on"ept# apply in general to any #y#te8

So8e prole8# "an e #ol!ed 8ore "leanly or


Kui"7ly with other non; or partially;REST
approa"he#

2ut then you "anEt really parti"ipate in the


We

The larger or 8ore foundational your #y#te8'


the 8ore you need REST
Copyright 2005 John Cowan under GPL F5
222

222 #y#te8# u#ually a##u8e that P(STed


do"u8ent# di#appear into ea"h partnerE#
internal u#ine## #y#te8#

2u#ine## pro"e##e# would a"tually wor7 etter


if treated li7e a We re#our"e

$n order i# a re#our"e

Ship8ent# and pay8ent# are #u;re#our"e#

$8a>on get# thi# 8o#tly right


Copyright 2005 John Cowan under GPL FD
(ther proto"ol#

(ther proto"ol# are not organi>ed around 1R4#


the way MTTP i#

They rea7 up the addre## #pa"e into pie"e#'


#o8e of whi"h donEt e!en ha!e 1R4#

MTTP wa# desi&ned to 8anipulate re#our"e#


laeled y 1R4#
Copyright 2005 John Cowan under GPL FF
Tunneling MTTP

4f you really do need non;MTTP tran#port'


tunnel MTTP o!er that tran#port

MTTP i# pretty #i8ple ;; a "ouple of header# i#


all you a#olutely need
Copyright 2005 John Cowan under GPL FG
Clarifying A#tateB
Copyright 2005 John Cowan under GPL FJ
Two 7ind# of #tate

$ppli"ation #tate i# the infor8ation ne"e##ary


to under#tand the "onteCt of an intera"tion

$uthori>ation and authenti"ation infor8ation are


eCa8ple# of appli"ation #tate

Re#our"e #tate i# the 7ind that the S in REST


refer# to

The Q#tatele##Q "on#traint 8ean# that all


8e##age# 8u#t in"lude all application #tate&
Copyright 2005 John Cowan under GPL G0
Re#our"e #tate

Change# in re#our"e #tate are una!oidale

So8eone ha# to P(ST new re#our"e# efore other#


"an GET the8

REST i# aout a!oiding i8pli"it or unna8ed


#tate5 re#our"e #tate i# na8ed y 1R4#

$ppli"ation #tate i# reKuired y the #er!er to


under#tand how to pro"e## a reKue#t
Copyright 2005 John Cowan under GPL G1
Se##ion #tate

Se##ion #tate i# al#o appli"ation #tate

4f you want a #e##ion' you often need #8arter


"lient# than a row#er

Spe"iali>ed "lient# "an 8anage oth


appli"ation and re#our"e #tate
Copyright 2005 John Cowan under GPL G2
Se##ion#

$ pur"ha#ing "lient "ould #end a #ingle MTTP


reKue#t 8entioning e!erything it wanted to
pur"ha#e in one 8e##age

Shopping "art# are for people' who ha!e


troule 7eeping #tate in their head#
Copyright 2005 John Cowan under GPL G9
The purpo#e of #tatele##ne##

Pre!ent# partial failure#

$llow# for #u#trate independen"e

Load;alan"ing

Ser!i"e interruption#
Copyright 2005 John Cowan under GPL G?
$nother 7ind of #tate

)on@t "onfu#e REST #tate with #tate;8a"hine


#tate

REST #tate i# the repre#entation of the !alue#


of the propertie# of a re#our"e

State 8a"hine# fit into REST when the #tate#


are eCpre##ed a# re#our"e# with lin7#
indi"ating tran#ition#
Copyright 2005 John Cowan under GPL G5
Hro8 where we are
to where we@d li7e to e
Copyright 2005 John Cowan under GPL GD
The A((P on the WeB theory

MTTP i# =u#t a tran#port layer etween o=e"t#

Ie##age# and o=e"t# are oth opaKue

(=e"t# =ealou#ly guard their pri!ate #tate


Copyright 2005 John Cowan under GPL GF
S8a#h the %pri!ate* #tate

Eli8inating pri!ate #tate let# u# de!elop


ar"hite"ture# that "an #"ale to larger de#ign#&

REST #y#te8# tran#fer the entire #tate of the


tran#a"tion at e!ery #tate tran#ition

3ou "an pi"7 up where you left off y 8erely


a""e##ing the 1R4 at a later ti8e' regardle## of
"lient or #er!er "hange#&
Copyright 2005 John Cowan under GPL GG
AIy o## =u#t want# it
on ti8e and under udgetB

$n analogy, (ur gene# want everyone to


reprodu"e

2ut that doe#n@t 8ean reprodu"ing will alway#


8a7e you any happier

4f your want to uild a we;a""e##ile tool7it


that a lot of people 8a7e u#e of' REST 8ay help

Hor a one;off pro=e"t written y a #8all group


of de!eloper#' REST 8ay e irrele!ant
Copyright 2005 John Cowan under GPL GJ
RPC "hara"teri>ed

E!ery o=e"t ha# it# own uniKue 8ethod#

Iethod# "an e re8otely in!o7ed o!er the


4nternet

$ #ingle 1R4 repre#ent# the end;point' and


thatE# the only "onta"t with the We

)ata hidden ehind 8ethod "all# and


para8eter#

)ata i# una!ailale to We appli"ation#


Copyright 2005 John Cowan under GPL J0
2ut in REST %=u#t to ru it in*

Every u#eful data o=e"t ha# an addre##

Re#our"e# the8#el!e# are the target# for


8ethod "all#

The li#t of 8ethod# i# fiCed for all re#our"e#


Copyright 2005 John Cowan under GPL J1
REST and RPC

REST i#' in a #en#e' a #pe"ie# of RPC' eC"ept the


8ethod# ha!e een defined in ad!an"e

Io#t RPC appli"ation# donEt adhere to the


REST philo#ophy

4t@# po##ile to wor7 with RPC;#tyle tool# to


produ"e REST re#ult#

0ot that people a"tually do #oO


Copyright 2005 John Cowan under GPL J2
Re8ote pro"edure#

Con#ider the #to"7 eCa8ple of a re8ote


pro"edure "alled AgetSto"7Pri"eB

Thi# i#nEt a re#our"e %!er' not noun*

4tE# not "lear what what it 8ean# to GET' P1T'


and P(ST to #o8ething "alled QgetSto"7Pri"eQ
Copyright 2005 John Cowan under GPL J9
REST =u#t RPC rena8ed:

2ut if we "hange the na8e fro8


QgetSto"7Pri"eQ to QCurrentSto"7Pri"eQ %a
noun*' all i# wellO

The differen"e# etween RPC and REST "an e


Kuite #utle

4f that were all' REST would e =u#t a de#ign


#tyle' not an ar"hite"ture
Copyright 2005 John Cowan under GPL J?
There are no neutral# there

REST i# incompatible with Qend;pointQ RPC

Either you addre## data o=e"t# or you addre##


Q#oftware "o8ponent#A

REST doe# the for8er

End;point RPC doe# the latter

3ou "an try to "ontort RPC proto"ol# into wor7ing on


data o=e"t 1R4#' ut then you end up re;in!enting a
non;#tandard !ariant of MTTP
Copyright 2005 John Cowan under GPL J5
Can REST really eat RPC:

4f REST wor7# and RPC doe#nEt' then ye#O

S($P egan a# pure RPC and ha# een 8o!ing


further and further away

S($P %and it# parent NIL;RPC* ha!e een


around for year# and yet there i# no 7iller app

REST "an point to the We it#elf a# proof that


4t Ju#t Wor7#
Copyright 2005 John Cowan under GPL JD
Two !iew# of P(ST

AP(ST let# you pa## a whole lot of para8eter#


and get #o8ething a"7' ypa##ing "a"he#&B

AP(ST let# you "reate new re#our"e# that are


related to old one#&B

The #e"ond i# the REST attitude


Copyright 2005 John Cowan under GPL JF
REST, an alien notion

RPC;o!er;MTTP i# well;8at"hed with "urrent


thin7ing

Ta7e an eCi#ting o=e"t 8odel' and a little


We;#pe"ifi" glue' and #i8ply eCport tho#e
interfa"e# to the We

The prole8# "reep in down the road


Copyright 2005 John Cowan under GPL JG
REST #ound# o8inou#

Co8pletely rethin7 your de#ign in ter8# of


generi" interfa"e#

2uild #er!let;#tyle i8ple8entation# of ea"h


re#our"e

1npa"7 and repa"7 ReKue#t and Re#pon#e


o=e"t#

The gluuuuue i# up to yooooou&


Copyright 2005 John Cowan under GPL JJ
REST #ound# o8inou#

Plenty of people do 7now how to de!elop


#er!let#

Still' 8o#t de!eloper# and data 8odeller# thin7


only in 1IL and ((P

REST i# potentially a# #ignifi"ant a "hange a#


the tran#ition fro8 pro"edure# to o=e"t#
Copyright 2005 John Cowan under GPL 100
AREST i# ha;ardB ;;RPC 2arie

4t #o8eti8e# ta7e# a# 8u"h wor7 to learn to


u#e one tool well than fi!e tool# adly

4n the long run you are etter off

NIL wa# ha;ard too for people u#ed to MTIL'


flat file#' and CSL

ASo8e people refu#ed to learn to u#e the


telephone& They don@t wor7 here any 8ore&B
Copyright 2005 John Cowan under GPL 101
Paul Pre#"od #how# u# the REST way
POST /purchase_orders HTTP/1.1
Host: accounting.mycompany.com
content-type:
application/purchase-order+xml
....
po!.../po!
Copyright 2005 John Cowan under GPL 102
$nd then there@# the S($P way
POST /generic_message_handler
content-type: application/SO"P+#$%
soap:en&elope!
soap:'ody!
su'mit-purchase-order!
destination!accounting.mycompany.com/destination!
po!.../po!
/su'mit-purchase-order!
/soap:'ody!
soap:en&elope!
Copyright 2005 John Cowan under GPL 109
Sta"7ing the de"7

0a8e#pa"e de"laration# would 8a7e the S($P


eCa8ple 8u"h igger

NIL i# not 8agi" piCie du#t, #o8eti8e# plain


teCt i# all you need

4n the ga>illion#;of;tran#a"tion#;per;#e"ond
world' the#e thing# "ount

)o 8ore with le##


Copyright 2005 John Cowan under GPL 10?
S($P
Copyright 2005 John Cowan under GPL 105
S($P, neither fi#h nor fowl

$ a#e fro8 whi"h to uild new proto"ol# and


tunnel the8 o!er eCi#ting appli"ation
proto"ol# %typi"ally MTTP*

$ 8ean# to eCtend the #e8anti"# of tho#e #a8e


appli"ation proto"ol#
Copyright 2005 John Cowan under GPL 10D
S($P "an e RPC or not

(riginally S($P wa# a pure RPC tran#port li7e


it# an"e#tor NIL;RPC

Iore re"ent !er#ion# of S($P pro8ote the le##


prole8ati" Ado"u8ent-literalB #tyle' whi"h i#
analogou# to e8ail,

0o eCpli"it 8ethod na8e

The re"ipient de"ide# what to do


Copyright 2005 John Cowan under GPL 10F
P(STing a S($P 8e##age

Wrap the ody in a S($P en!elope

P(ST it to an endpoint 1R4

$ re#pon#e "o8e# a"7' whi"h you 8u#t


unwrap

(r you 8ight get a fault' whi"h o!erride#


%older S($P* or dupli"ate# %newer S($P* the
MTTP re#pon#e "ode
Copyright 2005 John Cowan under GPL 10G
P(STing a S($P 8e##age

S($P u#e# it# en!elope for what new MTTP


header# "ould do

S($P pro!ide# the 8eta;8etadata Qa"torQ and


Q8u#t1nder#tandQ

4f the ody of the S($P 8e##age repre#ent# an


entity that i# eing P(STed to #o8ething' at
lea#t part of the REST #tyle i# pre#er!ed
Copyright 2005 John Cowan under GPL 10J
The ad!antage# of S($Ple## GET

Iore tool# out there that "an do MTTP get#


%proCie#' #pider#' row#er#* than "an interpret
your S($P 8ethod a# a getter

Re#our"e# that are gettale ha!e 1R4# that "an


e lin7ed to

S($P endpoint# #hould at lea#t pro!ide an


alternate interfa"e that allow# !anilla MTTP
getting
Copyright 2005 John Cowan under GPL 110
MTTP i# not a tran#port proto"ol

4f the ody of a P(ST or P1T i# not a pie"e of


repre#entational #tate' youEre not doing REST

MTTP already define# the#e 8ethod# and


doe#nEt need new one# in#ide the P(ST ody
Copyright 2005 John Cowan under GPL 111
MTTP i# not a tran#port proto"ol

S($P au#e# MTTP y treating it a# a tran#port


proto"ol li7e TCP

AMTTP only eCi#t# to "arry it#' na8ely S($P


8e##age#' with or without a 8ethod na8eB

MTTP i# an application protocol, it doe#nEt #end


it#' it tran#fer# repre#entational #tate
Copyright 2005 John Cowan under GPL 112
We Iethod #pe"ifi"ation

S($P 1&2 eCpo#e# the MTTP 8ethod through


the S($P inding

S($P "lient# "an u#e GET to retrie!e S($P


en!elope# that "ontain the #tate of the
re#our"e identified y the 1R4
Copyright 2005 John Cowan under GPL 119
We Iethod #pe"ifi"ation

Potentially radi"ally different fro8 the


"o88on u#e# of S($P 1&1

Will S($P 1&2 appli"ation# auto8ati"ally


e"o8e 8ore RESTful: 0ot a it

Io#t S($P u#er# will proaly "ontinue to u#e


S($P 1&2 in the #a8e way# a# S($P 1&1&
Copyright 2005 John Cowan under GPL 11?
Cleaning up "urrent pra"ti"e
Copyright 2005 John Cowan under GPL 115
Coo7ie#

$ re"eipt for appli"ation #tate handed out y


the #er!er

1#ing "oo7ie# i# eing #tateful,

0ot all appli"ation #tate i# "arried in the 8e##age

The "oo7ieE# referent i# held on the #er!er


Copyright 2005 John Cowan under GPL 11D
Coo7ie# arenEt all ad

$t lea#t there eCi#t# a referen"e to the #tate

The reKue#t "an e load alan"ed to #o8e


other #er!er within the #a8e tru#t do8ain for
pro"e##ing

2eyond that tru#t do8ain' "oo7ie# donEt 8ean


anything to anyody

That 8a7e# people paranoid aout the8


Copyright 2005 John Cowan under GPL 11F
Coo7ie prole8#

Coo7ie# rea7 visibility

Ca"he# donEt under#tand the8

Coo7ie# are ad authenti"ator#

They gi!e up #e"urity for effi"ien"y

Client# often #hut off "oo7ie# to pro!ide real or


i8agined pri!a"y
Copyright 2005 John Cowan under GPL 11G
6eeping #tate in the "oo7ie

Let# 1R4# e independent of the u#er #tate

2ut it de#troy# the "lientE# under#tanding of


#tate a# pre#ented y hyperteCt

4t rea7# the 2a"7 utton


Copyright 2005 John Cowan under GPL 11J
6eeping a reference to #tate

Storing #tate on the "lient pro!ide# RESTE#


#"alaility&

Site# with "lient #e##ion# on the a"7 end are


u#ually #e!eral order# of 8agnitude le##
#"alale than REST;a#ed appli"ation#

They al#o reKuire 8u"h 8ore "o8pleC a"7;


end engine# %J2EE' for eCa8ple*
Copyright 2005 John Cowan under GPL 120
6eeping identity in the "oo7ie

Coo7ie# are 8ore effi"ient than proper MTTP


authenti"ation

#er!er# and inter8ediarie# #i8ply ignore the8 for


8o#t 1R4# %e&g&' inline i8age#*

2ut the #er!er i# relying on #e"urity y


o#"urity

Cro##;#ite #"ripting and "oo7ie gue##ing are


real danger#
Copyright 2005 John Cowan under GPL 121
Tunneling

1#ing P(ST to #end data thatE# #uppo#ed to


8ean #o8ething other than P(ST to the
re"ipient i# tunneling

$d8ini#trator# dete#t tunneling and for good


rea#on

2e"au#e S($P i# a 8eta;appli"ation proto"ol'


tunneling i# it# 8iddle na8e
Copyright 2005 John Cowan under GPL 122
)onEt tunnel through port G0

Hirewall# and port# eCi#t for a rea#on

When you #how up at the airport' if you "lai8


that you are a pilot youEll proaly get wa!ed
through 8ore Kui"7ly& 2ut &&&

4tE# dangerou# to lie to the firewall #y#te8#


put up y people wor7ing for the #a8e
"o8pany you do' trying to prote"t it fro8 the
out#ide world
Copyright 2005 John Cowan under GPL 129
)onEt tunnel through port G0

Se"urity ad8ini#trator# will find a way to #hut


your RPC o!er port G0 down

Then youEll ha!e to add another layer of


ofu#"ation

4n the long run the eCtra layer will no longer


uy you a free pa## through the firewall

3ou end up with an ar8# ra"e of e#"alating


ofu#"ation and dete"tion
Copyright 2005 John Cowan under GPL 12?
$ppli"ation proto"ol# and #afety

$ppli"ation# proto"ol# pro!ide #afety


guarantee# y pro!iding a fiCed interfa"e

(nly li8ited thing# "an e done through the


interfa"e

SITP doe#nEt let you do anything ut #end


8ail

4t "anEt e u#ed to retrie!e file# unle##


#o8eody eCpli"itly in#tall# #oftware that
allow# #u"h tunneling
Copyright 2005 John Cowan under GPL 125
$ppli"ation proto"ol# and #afety

SITP doe#nEt in"lude #u"h tunneling feature#


y default

Con#eKuently it i# tru#ted and well deployed

%Spa8 i# not an SITP prole8 per se*

HiCed interfa"e# are #e"ure' e"au#e #oftware


i8ple8enting the8 only doe# what itE#
de#igned to do
Copyright 2005 John Cowan under GPL 12D
1#e MTTP a# MTTP

1#e MTTP e"au#e it i# prag8ati"

$l#o u#e MTTP as -TTP #o that it wor7# with'


not again#t the firewall #oftware and firewall
ad8ini#trator#

Ia7e ea"h 8e##age a# !i#ile a# po##ile to the


firewall' and in!i#ile and opaKue to "ra"7er#

Letting aritrary reKue#t# tunnel through your


firewall i# a#7ing to lo#e
Copyright 2005 John Cowan under GPL 12F
Plain MTTP !#& S($P on MTTP

See Paul Pre#"od@# eCa8ple# again

Whi"h one "an e readily filtered with


#e"urity #oftware:

Whi"h one "an a #y#ad8in in#pe"t and


under#tand in a logfile:
Copyright 2005 John Cowan under GPL 12G
Wor7ing with REST' not again#t it

Re"on#ider your appli"ationE# need# in ter8#


of the pro!ided interfa"e# and #e8anti"#

)onEt try to figure out how to #u!ert or


eCtend MTTP to en"o8pa## what you thin7
your appli"ation #e8anti"# are
Copyright 2005 John Cowan under GPL 12J
RESTafarian E8ail, an eCa8ple
Copyright 2005 John Cowan under GPL 190
RESTafarian E8ail

4f we were de#igning e8ail fro8 #"rat"h on


REST prin"iple#' what 8ight it loo7 li7e:

Thi# i# one possible way' not the (ne True REST


Way

REST i# nothing if not fleCile' pro!ided you


#ti"7 to the few prin"iple# weE!e already #een
Copyright 2005 John Cowan under GPL 191
Iail #er!er# 7eep outgoing 8ail

To po#t an e8ail' u#e P(STO

3our lo"al outound 8ail #er!er eCpo#e# a 1R4


where outound 8e##age# "an e po#ted

Se"urity 8a7e# #ure only authori>ed u#er# "an


po#t

The 8ail ne!er lea!e# the #er!er until the


#ender or the re"ipient de"ide to delete it
Copyright 2005 John Cowan under GPL 192
IailoC #er!er# 7eep inoC #tate

To read your 8ail' u#e GET to fet"h a #et of


hyperlin7# %ni"ely for8atted* that repre#ent
in"o8ing 8e##age#

GETting one lin7 #end# you to the 8ail #er!er


that ha# the 8e##age and retrie!e# it

)ELETE re8o!e# 8e##age# you no longer want


Copyright 2005 John Cowan under GPL 199
IailoC #er!er# 7eep inoC #tate

$r"hi!ed 8e##age# are di#played in !iew# you


"an GET

Holderi>ing i# P(STing a 8e##age "ontaining a


1R4 to the folder %whi"h it#elf ha# a 1R4*

Horwarding i# al8o#t li7e folderi>ing' ut to


#o8eone el#e@# inoC

Migher;le!el #er!i"e# li7e #ear"he# are done y


P(ST and "reate new re#our"e# that you "an
wait for or GET later
Copyright 2005 John Cowan under GPL 19?
Iail notifi"ation

Iail #er!er# ha!e to tell 8ailoC #er!er# that


8ail i# a!ailale

4nound #er!er# eCpo#e a 1R4 that "an e


P(STed to with a "heap 8e##age "ontaining
=u#t a 1R4
Copyright 2005 John Cowan under GPL 195
0o #pa8O

$ny re"ipient "an delete a 8e##age' #o =u#t


7eeping one "opy on the #pa88er@# 8ail
#er!er won@t wor7

Spa88er# would ha!e to 7eep >illion# of


"opie# on their 8ail #er!er#

That "o#t# RRRR and draw# attention

$ #pa8 no one get# to read i#nEt a #pa8


Copyright 2005 John Cowan under GPL 19D
0o #pa8O

(f "our#e a #pa88er "an "heat y u#ing a


#er!er that i8properly ignore# )ELETE#

2ut that only wor7# on"e' a# #u"h #er!er# get


la"7li#ted %and they "annot tri!ially hide
their identitie#*

0o #o"ial prole8 "an e completely #ol!ed y


te"hni"al fiCe#
Copyright 2005 John Cowan under GPL 19F
APo#t in ha#te' repent at lei#ureB

SITP 8ail on"e #ent "anEt e retrie!ed

Sender# "an u#e P1T or )ELETE to 8odify or


re8o!e their 8ail# e!en after po#ting the8

(f "our#e' that doe#nEt "hange the #tate in the


re"ipientE# head
Copyright 2005 John Cowan under GPL 19G
Related ar"hite"ture#
Copyright 2005 John Cowan under GPL 19J
Sy#te8# !#& appli"ation# progra88ing

Sy#te8# progra88ing e8pha#i>e# 8a7ing the


new do8ain fit into the eCi#ting generi"
interfa"e#

$ppli"ation# progra88ing 8odel# the


appli"ation do8ain pre"i#ely fir#t' worrie#
aout integration afterward# %if at all*
Copyright 2005 John Cowan under GPL 1?0
Thought# of a #y#te8# gee7

4f appli"ation# progra88er# thought 8ore li7e


#y#te8# progra88er#' the world would e a
etter pla"e

4f a prole8 i# not intere#ting' generali>e it


until it i#' then #ol!e the general prole8
Copyright 2005 John Cowan under GPL 1?1
The 1niC Way

1niC ha# de#troyed all it# "o8petitor# ut one


%to the point where 8any people "anEt e!en
na8e tho#e other "o8petitor#*

The "ore of 1niC i# it# #oftware tool#


philo#ophy,

the aility to #tring together lot# of little #pe"ial;


purpo#e tool# with generi" interfa"e#
Copyright 2005 John Cowan under GPL 1?2
The 1niC Way

E!erything i# a file

Hile# ha!e a generi" interfa"e

$ll re#our"e# in the #y#te8 "ould e a""e##ed


through the#e narrow interfa"e#

So8e thing# were alway# eC"eption#

1niC networ7ing ro7e thi# philo#ophy

The Plan J re#ear"h (S re#tored it' douled and in


#pade#
Copyright 2005 John Cowan under GPL 1?9
REST fro8 a 1niC !iewpoint

Re#our"e# rather than file#

1R4 #pa"e in#tead of the file#y#te8

$ #lightly different %e!en narrower* generi"


interfa"e

2ut the fo"u# i# the #a8e, a generi" #hared


a#tra"tion' not point;to;point interfa"e
"oordination&
Copyright 2005 John Cowan under GPL 1??
(ther "oordination en!iron8ent#

4n Linda' you get and put anony8ou# tuple#

4n 104N #hell progra88ing' autono8ou#


progra8# read and write fro8 pipe#

Plan J eCtend# the file#y#te8 to e a uni!er#al


na8e#pa"e

To write a de!i"e dri!er' you i8ple8ent open


and close and read and write and ioctl and &&&
Copyright 2005 John Cowan under GPL 1?5
Hinal thought#
Copyright 2005 John Cowan under GPL 1?D
Ma# RPC really failed:

(0C and )CE RPC are the a#i# of,

Plenty of enterpri#e #oftware

The widely deployed 0HS

C(R2$ and )C(I are in lots of indu#trial;


#trength enterpri#e #oftware&
Copyright 2005 John Cowan under GPL 1?F
REST and WS;<

4n the end' WS;< i# =u#t there' li7e Window#

REST people need to wor7 to en#ure that the


WS;< #ta"7 i# #uffi"iently ri"h to e u#eful to
the8

Two different de#ign #tyle#' infor8ed y


different need# and !alue#

They #hould #till #hare a te"hnology a#e a#


8u"h a# po##ile %and no 8ore*
Copyright 2005 John Cowan under GPL 1?G
3ouEre 8y only hope

The only thing that "an really 8a7e REST wor7


for u# all i# road edu"ation in,

What' eCa"tly' the REST #tyle is

-ow to de#ign to it

Why itE# a Good Thing

2ut that@# why you@re here

You might also like