DESIGNING HTTP INTERFACES AND RESTFUL WEB SERVICES David Zuelke - - PowerPoint PPT Presentation

designing http interfaces and restful web services david
SMART_READER_LITE
LIVE PREVIEW

DESIGNING HTTP INTERFACES AND RESTFUL WEB SERVICES David Zuelke - - PowerPoint PPT Presentation

DESIGNING HTTP INTERFACES AND RESTFUL WEB SERVICES David Zuelke David Zlke http://en.wikipedia.org/wiki/File:Mnchen_Panorama.JPG Founder Lead Developer @dzuelke THE OLDEN DAYS Before REST was En Vogue


slide-1
SLIDE 1

DESIGNING HTTP INTERFACES AND RESTFUL WEB SERVICES

slide-2
SLIDE 2

David Zuelke

slide-3
SLIDE 3

David Zülke

slide-4
SLIDE 4
slide-5
SLIDE 5 http://en.wikipedia.org/wiki/File:München_Panorama.JPG
slide-6
SLIDE 6

Founder

slide-7
SLIDE 7
slide-8
SLIDE 8

Lead Developer

slide-9
SLIDE 9
slide-10
SLIDE 10

@dzuelke

slide-11
SLIDE 11

THE OLDEN DAYS

Before REST was En Vogue

slide-12
SLIDE 12

http://www.acme.com/index.php?action=zomg&page=lol

slide-13
SLIDE 13

along came

slide-14
SLIDE 14

dis is srs SEO bsns

slide-15
SLIDE 15

and said

slide-16
SLIDE 16

NEIN NEIN NEIN NEIN DAS IST VERBOTEN

slide-17
SLIDE 17

at least if they were

slide-18
SLIDE 18
slide-19
SLIDE 19

so we had to make URLs "SEO friendly"

slide-20
SLIDE 20

http://www.acme.com/zomg/lol

slide-21
SLIDE 21

and then things got out of control

slide-22
SLIDE 22

because nobody really had a clue

slide-23
SLIDE 23

http://acme.com/videos/latest/hamburgers

slide-24
SLIDE 24

http://acme.com/search/lolcats/pictures/yes/1/200

slide-25
SLIDE 25
  • h dear…
slide-26
SLIDE 26

THE RISE OF WEB SERVICES

Ohai, I'm ur CEO, I canhaz SOAP API plz, today, kthx?

slide-27
SLIDE 27 POST ¡/soapendpoint.php ¡HTTP/1.1 Host: ¡localhost Content-­‑Type: ¡text/xml; ¡charset=utf-­‑8 <?xml ¡version="1.0" ¡encoding="UTF-­‑8"?> <SOAP-­‑ENV:Envelope ¡xmlns:SOAP-­‑ENV="http://schemas.xmlsoap.org/soap/envelope/"> ¡ ¡<SOAP-­‑ENV:Body> ¡ ¡ ¡ ¡<ns1:getProduct ¡xmlns:ns1="http://agavi.org/sampleapp"> ¡ ¡ ¡ ¡ ¡ ¡<id>123456</id> ¡ ¡ ¡ ¡</ns1:getProduct> ¡ ¡</SOAP-­‑ENV:Body> </SOAP-­‑ENV:Envelope> HTTP/1.1 ¡200 ¡OK Content-­‑Type: ¡text/xml; ¡charset=utf-­‑8 <?xml ¡version="1.0" ¡encoding="UTF-­‑8"?> <SOAP-­‑ENV:Envelope ¡xmlns:SOAP-­‑ENV="http://schemas.xmlsoap.org/soap/envelope/"> ¡ ¡<SOAP-­‑ENV:Body> ¡ ¡ ¡ ¡<ns1:getProductResponse ¡xmlns:ns1="http://agavi.org/sampleapp"> ¡ ¡ ¡ ¡ ¡ ¡<product> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡<id>123456</id> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡<name>Red ¡Stapler</name> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡<price>3.14</price> ¡ ¡ ¡ ¡ ¡ ¡</product> ¡ ¡ ¡ ¡</ns1:getProductResponse> ¡ ¡</SOAP-­‑ENV:Body> </SOAP-­‑ENV:Envelope>
slide-28
SLIDE 28 POST ¡/soapendpoint.php ¡HTTP/1.1 Host: ¡localhost Content-­‑Type: ¡text/xml; ¡charset=utf-­‑8 <?xml ¡version="1.0" ¡encoding="UTF-­‑8"?> <SOAP-­‑ENV:Envelope ¡xmlns:SOAP-­‑ENV="http://schemas.xmlsoap.org/soap/envelope/"> ¡ ¡<SOAP-­‑ENV:Body> ¡ ¡ ¡ ¡<ns1:getProduct ¡xmlns:ns1="http://agavi.org/sampleapp"> ¡ ¡ ¡ ¡ ¡ ¡<id>987654</id> ¡ ¡ ¡ ¡</ns1:getProduct> ¡ ¡</SOAP-­‑ENV:Body> </SOAP-­‑ENV:Envelope> HTTP/1.1 ¡500 ¡Internal ¡Service ¡Error Content-­‑Type: ¡text/xml; ¡charset=utf-­‑8 <?xml ¡version="1.0" ¡encoding="UTF-­‑8"?> <SOAP-­‑ENV:Envelope ¡xmlns:SOAP-­‑ENV="http://schemas.xmlsoap.org/soap/envelope/"> ¡ ¡<SOAP-­‑ENV:Body> ¡ ¡ ¡ ¡<SOAP-­‑ENV:Fault> ¡ ¡ ¡ ¡ ¡ ¡<faultcode>SOAP-­‑ENV:Server</faultcode> ¡ ¡ ¡ ¡ ¡ ¡<faultstring>Unknown ¡Product ¡</faultstring> ¡ ¡ ¡ ¡</SOAP-­‑ENV:Fault> ¡ ¡</SOAP-­‑ENV:Body> </SOAP-­‑ENV:Envelope>
slide-29
SLIDE 29

SOAP sucks, said everyone

slide-30
SLIDE 30

let's build APIs without the clutter, they said

slide-31
SLIDE 31

example: the http://joind.in/ API

slide-32
SLIDE 32 POST ¡/api/talk ¡HTTP/1.1 Host: ¡joind.in Content-­‑Type: ¡text/xml; ¡charset=utf-­‑8 <?xml ¡version="1.0" ¡encoding="UTF-­‑8"?> <request> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡<auth> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡<user>Chuck ¡Norris</user> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡<pass>roundhousekick</pass> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡</auth> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡<action ¡type="getdetail"> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡<talk_id>42</talk_id> ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡</action> </request> HTTP/1.1 ¡200 ¡OK Content-­‑Type: ¡text/xml; ¡charset=utf-­‑8 <?xml ¡version="1.0" ¡encoding="UTF-­‑8"?> <response> ¡ <item> ¡ ¡ <talk_title>My ¡Test ¡Talk</talk_title> ¡ ¡ <talk_desc>This ¡is ¡a ¡sample ¡talk ¡description</talk_desc> ¡ ¡ <ID>42</ID> ¡ </item> </response>
slide-33
SLIDE 33

PROBLEMS WITH THIS API

  • Always a POST
  • Doesn't use HTTP Authentication
  • Operation information is enclosed in the request ("getdetail")
  • Nothing there is cacheable
  • Everything through one endpoint (/api/talks for talks)
slide-34
SLIDE 34

Level 0 in the Richardson Maturity Model: Plain old XML over the wire in an RPC fashion

slide-35
SLIDE 35

Room for improvement: use one URI for each resource “ “

slide-36
SLIDE 36

That would be Level 1 in Richardson's Maturity Model

slide-37
SLIDE 37

Level 0 and Level 1 are a bag of hurt. Do not use them. Ever.

slide-38
SLIDE 38

ALONG CAME ROY FIELDING

And Gave Us REST

slide-39
SLIDE 39

that was awesome

slide-40
SLIDE 40

because everyone could say

slide-41
SLIDE 41

I haz REST nao

slide-42
SLIDE 42

when in fact

slide-43
SLIDE 43

they bloody didn’t

slide-44
SLIDE 44

REST

What Does That Even Mean?

slide-45
SLIDE 45

REpresentational State Transfer

slide-46
SLIDE 46

Roy Thomas Fielding: Architectural styles and the design of network based software architectures.

slide-47
SLIDE 47
  • Client-Server
  • Stateless
  • Cacheable
  • Layered System
  • Code on Demand (optional)
  • Uniform Interface

REST CONSTRAINTS

slide-48
SLIDE 48
  • A URL identifies a Resource
  • Methods perform operations on resources
  • The operation is implicit and not part of the URL
  • A hypermedia format is used to represent the data
  • Link relations are used to navigate a service

UNIFORM INTERFACE

slide-49
SLIDE 49

a web page is not a resource

slide-50
SLIDE 50

it is a (complete) representation of a resource

slide-51
SLIDE 51 GET ¡/products/ ¡HTTP/1.1 Host: ¡acme.com Accept: ¡application/json HTTP/1.1 ¡200 ¡OK Content-­‑Type: ¡application/json; ¡charset=utf-­‑8 Allow: ¡GET, ¡POST [ ¡ ¡{ ¡ ¡ ¡ ¡id: ¡1234, ¡ ¡ ¡ ¡name: ¡"Red ¡Stapler", ¡ ¡ ¡ ¡price: ¡3.14, ¡ ¡ ¡ ¡location: ¡"http://acme.com/products/1234" ¡ ¡} ]

GETTING JSON BACK

slide-52
SLIDE 52 GET ¡/products/ ¡HTTP/1.1 Host: ¡acme.com Accept: ¡application/xml HTTP/1.1 ¡200 ¡OK Content-­‑Type: ¡application/xml; ¡charset=utf-­‑8 Allow: ¡GET, ¡POST <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <products ¡xmlns="urn:com.acme.products" ¡xmlns:xl="http://www.w3.org/1999/xlink"> ¡ ¡<product ¡id="1234" ¡xl:type="simple" ¡xl:href="http://acme.com/products/1234"> ¡ ¡ ¡ ¡<name>Red ¡Stapler</name> ¡ ¡ ¡ ¡<price ¡currency="EUR">3.14</price> ¡ ¡</product> </products>

GETTING XML BACK

slide-53
SLIDE 53

but those are not hypermedia formats!

slide-54
SLIDE 54

(more on that a bit later)

slide-55
SLIDE 55 GET ¡/products/ ¡HTTP/1.1 Host: ¡acme.com Accept: ¡application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,*/*;q=0.5 User-­‑Agent: ¡Mozilla/5.0 ¡(Macintosh; ¡U; ¡Intel ¡Mac ¡OS ¡X ¡10_5_8; ¡en-­‑us) ¡AppleWebKit… HTTP/1.1 ¡200 ¡OK Content-­‑Type: ¡text/html; ¡charset=utf-­‑8 Allow: ¡GET, ¡POST <html ¡lang="en"> ¡ ¡<head> ¡ ¡ ¡ ¡<meta ¡http-­‑equiv="Content-­‑Type" ¡content="text/html; ¡charset=UTF-­‑8"></meta> ¡ ¡ ¡ ¡<title>ACME ¡Inc. ¡Products</title> ¡ ¡</head> ¡ ¡<body> ¡ ¡ ¡ ¡<h1>Our ¡Incredible ¡Products</h1> ¡ ¡ ¡ ¡<ul ¡id="products"> ¡ ¡ ¡ ¡ ¡ ¡<li><a ¡href="http://acme.com/products/1234">Red ¡Stapler</a> ¡(€3.14)</li> ¡ ¡ ¡ ¡</ul> ¡ ¡</body> </html>

AND FINALLY, HTML

slide-56
SLIDE 56

VOLUME ONE

Designing an HTTP Interface

slide-57
SLIDE 57

FIRST: DEFINE RESOURCES

A Good Approach: Structure Your URLs

slide-58
SLIDE 58

BAD URLS

  • http://www.acme.com/product/
  • http://www.acme.com/product/filter/cats/desc
  • http://www.acme.com/product/1234
  • http://www.acme.com/photos/product/1234
  • http://www.acme.com/photos/product/1234/new
  • http://www.acme.com/photos/product/1234/5678

WTF? photo or product ID? new what?

slide-59
SLIDE 59

GOOD URLS

  • http://www.acme.com/products/
  • http://www.acme.com/products/?filter=cats&sort=desc
  • http://www.acme.com/products/1234
  • http://www.acme.com/products/1234/photos/
  • http://www.acme.com/products/1234/photos/?sort=latest
  • http://www.acme.com/products/1234/photos/5678

a list of products filtering is a query a single product all photos

slide-60
SLIDE 60

now here's the ironic part

slide-61
SLIDE 61

URLs don't matter once you have a fully RESTful interface

slide-62
SLIDE 62

but it’s helpful to think in terms of resources

slide-63
SLIDE 63

SECOND: USE RESOURCES

CRUD, but not really

slide-64
SLIDE 64

COLLECTION OPERATIONS

  • http://www.acme.com/products/
  • GET to retrieve a list of products
  • POST to create a new product
  • returns
  • 201 Created
  • Location: http://www.acme.com/products/1235
slide-65
SLIDE 65

ITEM OPERATIONS

  • http://www.acme.com/products/1234
  • GET to retrieve
  • PUT to update
  • DELETE to, you guessed it, delete
slide-66
SLIDE 66

and remember

slide-67
SLIDE 67

don't let the server maintain client state (e.g. cookies)

slide-68
SLIDE 68

Now we are at Level 2 in RMM

slide-69
SLIDE 69

RMM LEVEL 2

  • Use HTTP verbs
  • GET (safe and idempotent)
  • POST (unsafe, not idempotent)
  • PUT & DELETE (unsafe, idempotent)
  • Use HTTP status codes to indicate result success
  • e.g. HTTP/1.1 409 Conflict
slide-70
SLIDE 70

THE TWITTER API

Not RESTful, And Not Even Getting HTTP Right :(

slide-71
SLIDE 71

mind you we're not even inspecting the RESTfulness

slide-72
SLIDE 72

we're just looking at Twitter's API from an HTTP perspective

slide-73
SLIDE 73

CURRENT STATE

  • GET http://api.twitter.com/1/statuses/show/12345.json
  • POST http://api.twitter.com/1/statuses/update.json
  • DELETE http://api.twitter.com/1/statuses/destroy/12345.json
  • GET http://api.twitter.com/1/statuses/retweets/12345.json
  • PUT http://api.twitter.com/1/statuses/retweet/12345.json

Doesn’t allow Accept header Why a PUT? Why the difference? Posts to auth’d user! “DELETE destroy” , RPC much?

slide-74
SLIDE 74

COULD BE SO MUCH SIMPLER

  • http://twitter.com/username/statuses/
  • POST to create a new tweet
  • http://twitter.com/username/statuses/12345
  • DELETE deletes (PUT could be used for updates)
  • http://twitter.com/username/statuses/12345/retweets/
  • POST creates a new retweet
slide-75
SLIDE 75

INTERMISSION

What's the Biggest Reason for the Success of the Web?

slide-76
SLIDE 76

WWW

slide-77
SLIDE 77

first data exchange system

slide-78
SLIDE 78

planetary scale

slide-79
SLIDE 79
slide-80
SLIDE 80
slide-81
SLIDE 81

why is that possible?

slide-82
SLIDE 82

Hyperlinks!

slide-83
SLIDE 83

no tight coupling!

slide-84
SLIDE 84

loosely coupled by design

slide-85
SLIDE 85

no notification infrastructure

slide-86
SLIDE 86

HTTP/1.1 404 Not Found

slide-87
SLIDE 87

embraces failure

slide-88
SLIDE 88

more information != more friction

slide-89
SLIDE 89

no limits to scalability

slide-90
SLIDE 90

WWW is protocol-centric

slide-91
SLIDE 91

VOLUME TWO

RESTful Services with Hypermedia

slide-92
SLIDE 92

THE UNIFORM INTERFACE

  • Identification of Resources (e.g. through URIs)
  • Representations are conceptually separate!
  • Manipulation Through Representations (i.e. they are complete)
  • Self-Descriptive Messages (containing all information)
  • Hypermedia As The Engine Of Application State ("HATEOAS")

magic awesomesauce essential to REST

slide-93
SLIDE 93

HATEOAS

The Missing Piece in the Puzzle

slide-94
SLIDE 94

ONE LAST PIECE IS MISSING

  • How does a client know what to do with representations?
  • How do you go to the “next” operation?
  • What are the URLs for creating subordinate resources?
  • Where is the contract for the service?
slide-95
SLIDE 95

HYPERMEDIA AS THE ENGINE OF APPLICATION STATE

  • Use links to allow clients to discover locations and operations
  • Link relations are used to express the possible options
  • Clients do not need to know URLs, so they can change
  • The entire application workflow is abstracted, thus changeable
  • The hypermedia type itself could be versioned if necessary
  • No breaking of clients if the implementation is updated!
slide-96
SLIDE 96

(X)HTML and Atom are Hypermedia formats

slide-97
SLIDE 97

Or you roll your own...

slide-98
SLIDE 98 GET ¡/products/1234 ¡HTTP/1.1 Host: ¡acme.com Accept: ¡application/vnd.com.acme.shop+xml HTTP/1.1 ¡200 ¡OK Content-­‑Type: ¡application/vnd.come.acme.shop+xml; ¡charset=utf-­‑8 Allow: ¡GET, ¡PUT, ¡DELETE <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <product ¡xmlns="urn:com.acme.prods" ¡xmlns:atom="http://www.w3.org/2005/Atom"> ¡ ¡<id>1234</id> ¡ ¡<name>Red ¡Stapler</name> ¡ ¡<price ¡currency="EUR">3.14</price> ¡ ¡<atom:link ¡rel="payment" ¡type="application/vnd.com.acme.shop+xml" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡href="http://acme.com/products/1234/payment"/> </product>

re-use Atom for link relations meaning defined in IANA Link Relations list

A CUSTOM MEDIA TYPE

Remind clients of Uniform Interface :)

slide-99
SLIDE 99

boom, RMM Level 3

slide-100
SLIDE 100

XML is really good for hypermedia formats

slide-101
SLIDE 101

(hyperlinks, namespaced attributes, re-use of formats, …)

slide-102
SLIDE 102

JSON is more difficult

slide-103
SLIDE 103

(no hyperlinks, no namespaces, no element attributes)

slide-104
SLIDE 104 <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <product ¡xmlns="urn:com.acme.prods" ¡xmlns:atom="http://www.w3.org/2005/xlink"> ¡ ¡<id>1234</id> ¡ ¡<name>Red ¡Stapler</name> ¡ ¡<price ¡currency="EUR">3.14</price> ¡ ¡<atom:link ¡rel="payment" ¡type="application/com.acme.shop+xml" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡href="http://acme.com/products/1234/payment"/> </product> { ¡ ¡id: ¡1234, ¡ ¡name: ¡"Red ¡Stapler", ¡ ¡price: ¡{ ¡ ¡ ¡ ¡amount: ¡3.14, ¡ ¡ ¡ ¡currency: ¡"EUR" ¡ ¡}, ¡ ¡links: ¡[ ¡ ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡ ¡rel: ¡"payment", ¡ ¡ ¡ ¡ ¡ ¡type: ¡"application/vnd.com.acme.shop+json", ¡ ¡ ¡ ¡ ¡ ¡href: ¡"http://acme.com/products/1234/payment" ¡ ¡ ¡ ¡} ¡ ¡] }

XML VERSUS JSON

slide-105
SLIDE 105

also, JSON is hard to evolve without breaking clients

slide-106
SLIDE 106 <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <products ¡xmlns="http://acme.com/shop/products"> ¡ ¡<product ¡id="123"> ¡ ¡ ¡ ¡<name>Bacon</name> ¡ ¡ ¡ ¡<price>5.99</price> ¡ ¡</product> </products>
slide-107
SLIDE 107 <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <products ¡xmlns="http://acme.com/shop/products"> ¡ ¡<product ¡id="123"> ¡ ¡ ¡ ¡<name>Bacon</name> ¡ ¡ ¡ ¡<price>5.99</price> ¡ ¡ ¡ ¡OMNOMNOM ¡Bacon ¡ ¡</product> </products>
slide-108
SLIDE 108 <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <products ¡xmlns="http://acme.com/shop/products"> ¡ ¡<product ¡id="123"> ¡ ¡ ¡ ¡<name>Bacon</name> ¡ ¡ ¡ ¡<price>5.99</price> ¡ ¡ ¡ ¡<price ¡currency="EUR">4.49</price> ¡ ¡</product> </products>
slide-109
SLIDE 109 <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <products ¡xmlns="http://acme.com/shop/products"> ¡ ¡<product ¡id="123"> ¡ ¡ ¡ ¡<name ¡xml:lang="en">Bacon</name> ¡ ¡ ¡ ¡<name ¡xml:lang="de">Speck</name> ¡ ¡ ¡ ¡<price>5.99</price> ¡ ¡</product> </products>
slide-110
SLIDE 110 <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <products ¡xmlns="http://acme.com/shop/products"> ¡ ¡<product ¡id="123"> ¡ ¡ ¡ ¡<name ¡xml:lang="en">Bacon</name> ¡ ¡ ¡ ¡<name ¡xml:lang="de">Speck</name> ¡ ¡ ¡ ¡<price>5.99</price> ¡ ¡ ¡ ¡<link ¡rel="category" ¡href="..." ¡/> ¡ ¡</product> </products>
slide-111
SLIDE 111

and hey

slide-112
SLIDE 112

without hypermedia, your HTTP interface is not RESTful

slide-113
SLIDE 113

that’s totally fine and sometimes even the only way to do it

slide-114
SLIDE 114

(e.g. CouchDB or S3 are never going to be RESTful)

slide-115
SLIDE 115

just avoid calling it a "REST API" :)

slide-116
SLIDE 116

good hypermedia format example: the Lovefilm API

slide-117
SLIDE 117 <?xml ¡version="1.0" ¡encoding="utf-­‑8" ¡standalone="yes"?> <search> ¡ ¡<total_results>6</total_results> ¡ ¡<items_per_page>1</items_per_page> ¡ ¡<start_index>1</start_index> ¡ ¡<link ¡href="http://openapi.lovefilm.com/catalog/games?start_index=1&amp;items_per_page=1&amp;term=old" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡rel="self" ¡title="self"/> ¡ ¡<link ¡href="http://openapi.lovefilm.com/catalog/games?start_index=2&amp;items_per_page=1&amp;term=old" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡rel="next" ¡title="next"/> ¡ ¡<link ¡href="http://openapi.lovefilm.com/catalog/games?start_index=6&amp;items_per_page=1&amp;term=old" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡rel="last" ¡title="last"/> ¡ ¡<catalog_title> ¡ ¡ ¡ ¡<can_rent>true</can_rent> ¡ ¡ ¡ ¡<release_date>2003-­‑09-­‑12</release_date> ¡ ¡ ¡ ¡<title ¡full="Star ¡Wars: ¡Knights ¡of ¡the ¡Old ¡Republic" ¡clean="Star ¡Wars: ¡Knights ¡of ¡the ¡Old ¡Republic"/> ¡ ¡ ¡ ¡<id>http://openapi.lovefilm.com/catalog/title/59643</id> ¡ ¡ ¡ ¡<adult>false</adult> ¡ ¡ ¡ ¡<number_of_ratings>574</number_of_ratings> ¡ ¡ ¡ ¡<rating>4</rating> ¡ ¡ ¡ ¡<category ¡scheme="http://openapi.lovefilm.com/categories/catalog" ¡term="games"/> ¡ ¡ ¡ ¡<category ¡scheme="http://openapi.lovefilm.com/categories/format" ¡term="Xbox"/> ¡ ¡ ¡ ¡<category ¡scheme="http://openapi.lovefilm.com/categories/genres" ¡term="Adventure"/> ¡ ¡ ¡ ¡<category ¡scheme="http://openapi.lovefilm.com/categories/genres" ¡term="Role-­‑playing"/> ¡ ¡ ¡ ¡<category ¡scheme="http://openapi.lovefilm.com/categories/certificates/bbfc" ¡term="TBC"/> ¡ ¡ ¡ ¡<link ¡href="http://openapi.lovefilm.com/catalog/title/59643/synopsis" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡rel="http://schemas.lovefilm.com/synopsis" ¡title="synopsis"/> ¡ ¡ ¡ ¡<link ¡href="http://openapi.lovefilm.com/catalog/title/59643/reviews" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡rel="http://schemas.lovefilm.com/reviews" ¡title="reviews"/> ¡ ¡ ¡ ¡<link ¡href="http://www.lovefilm.com/product/59643-­‑Star-­‑Wars-­‑Knights-­‑of-­‑the-­‑Old-­‑Republic.html?cid=LFAPI" ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡rel="alternate" ¡title="web ¡page"/> ¡ ¡</catalog_title> </search>
slide-118
SLIDE 118

ROOM FOR IMPROVEMENT IN THE LOVEFILM API

  • Uses application/xml instead of a custom media type
  • Once that is fixed, all the link elements could also have a

“type” attribute indicating the media type

  • Should use XML namespaces on the root element, with one

namespace per type (e.g. “urn:com.lovefilm.api.item”, “urn:com.lovefilm.api.searchresult” and so on)

  • That way, clients can determine the resource type easily
slide-119
SLIDE 119

another great RESTful API: Huddle

slide-120
SLIDE 120 <document ¡ ¡xmlns="http://schema.huddle.net/2011/02/" ¡ ¡title="TPS ¡report ¡May ¡2010" ¡ ¡description="relentlessly ¡mundane ¡and ¡enervating."> ¡ ¡ ¡ ¡<link ¡rel="self" ¡href="..." ¡/> ¡ ¡<link ¡rel="parent" ¡href="..." ¡title="..."/> ¡ ¡<link ¡rel="edit" ¡href="..." ¡/> ¡ ¡<link ¡rel="delete" ¡href="..." ¡/> ¡ ¡<link ¡rel="content" ¡href="..." ¡title="..." ¡type="..." ¡/> ¡ ¡<link ¡rel="thumb" ¡href="..." ¡/> ¡ ¡<link ¡rel="version-­‑history" ¡href="..." ¡/> ¡ ¡<link ¡rel="create-­‑version" ¡href="..." ¡/> ¡ ¡<link ¡rel="comments" ¡href="..." ¡/> ¡ ¡ ¡ ¡<actor ¡name="Peter ¡Gibson" ¡rel="owner"> ¡ ¡ ¡ ¡<link ¡rel="self" ¡href="..." ¡/> ¡ ¡ ¡ ¡<link ¡rel="avatar" ¡href="..." ¡type="image/jpg" ¡/> ¡ ¡ ¡ ¡<link ¡rel="alternate" ¡href="..." ¡type="text/html" ¡/> ¡ ¡</actor> ¡ ¡ ¡ ¡<actor ¡name="Barry ¡Potter" ¡rel="updated-­‑by"> ¡ ¡ ¡ ¡<link ¡rel="self" ¡href="..." ¡/> ¡ ¡ ¡ ¡<link ¡rel="avatar" ¡href="..." ¡type="image/jpg" ¡/> ¡ ¡ ¡ ¡<link ¡rel="alternate" ¡href="..." ¡type="text/html" ¡/> ¡ ¡</actor> ¡ ¡ ¡ ¡<size>19475</size> ¡ ¡ ¡ ¡<version>98</version> ¡ ¡<created>2007-­‑10-­‑10T09:02:17Z</created> ¡ ¡<updated>2011-­‑10-­‑10T09:02:17Z</updated> ¡ ¡<processingStatus>Complete</processingStatus> ¡ ¡<views>9</views> </document>
slide-121
SLIDE 121

ROOM FOR IMPROVEMENT IN THE HUDDLE API

  • Uses custom rels like “thumb” or “avatar” not defined in the

IANA registry (http://www.iana.org/assignments/link-relations)

  • Risk of collisions and ambiguity; should use something like

“http://rels.huddle.net/thumb” instead.

  • Uses one global XML schema and namespace for all entities
  • Clients cannot detect entity type based on namespace
  • Difficult to evolve schema versions independently
slide-122
SLIDE 122

API VERSIONING

Media Types To The Rescue!

slide-123
SLIDE 123

why not api.myservice.com/v1/foo/bar? and then api.myservice.com/v2/foo/bar?

slide-124
SLIDE 124

different URLs means different resources!

slide-125
SLIDE 125

also, keep bookmarks (by machines) in mind

slide-126
SLIDE 126 GET ¡/products ¡HTTP/1.1 Host: ¡acme.com Accept: ¡application/vnd.com.myservice+xml HTTP/1.1 ¡200 ¡OK Content-­‑Type: ¡application/vnd.com.myservice+xml; ¡charset=utf-­‑8 Allow: ¡GET, ¡POST <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <products ¡xmlns="urn:com.acme.products" ¡xmlns:xl="http://www.w3.org/1999/xlink"> ¡ ¡<product ¡id="1234" ¡xl:type="simple" ¡xl:href="http://acme.com/products/1234"> ¡ ¡ ¡ ¡<name>Red ¡Stapler</name> ¡ ¡ ¡ ¡<price ¡currency="EUR">3.14</price> ¡ ¡</product> </products>

API VERSION 1

slide-127
SLIDE 127

(some years pass...)

slide-128
SLIDE 128 GET ¡/products ¡HTTP/1.1 Host: ¡acme.com Accept: ¡application/vnd.com.myservice.v2+xml HTTP/1.1 ¡200 ¡OK Content-­‑Type: ¡application/vnd.com.myservice.v2+xml; ¡charset=utf-­‑8 Allow: ¡GET, ¡POST <?xml ¡version="1.0" ¡encoding="utf-­‑8"?> <products ¡xmlns="urn:com.acme.products" ¡xmlns:xl="http://www.w3.org/1999/xlink"> ¡ ¡<product ¡id="1234" ¡xl:type="simple" ¡xl:href="http://acme.com/products/1234"> ¡ ¡ ¡ ¡<name>Red ¡Stapler</name> ¡ ¡ ¡ ¡<price ¡currency="EUR">3.14</price> ¡ ¡ ¡ ¡<availability>false</availability> ¡ ¡</product> </products>

API VERSION 2

slide-129
SLIDE 129

clients can’t upgrade protocol for known URLs!

slide-130
SLIDE 130

Also, imagine every install of phpBB or Drupal had an API

slide-131
SLIDE 131

If the version is in the URL, clients need to regex those

slide-132
SLIDE 132

http://sharksforum.org/community/api/v1/threads/102152

slide-133
SLIDE 133

http://forum.sharksforum.org/api/v1/threads/102152

slide-134
SLIDE 134

that would be fail

slide-135
SLIDE 135
  • r what if another forum software wants the same API?
slide-136
SLIDE 136

also would have to use “/v1/” in their URLs

slide-137
SLIDE 137

URI based versioning kills interoperability

slide-138
SLIDE 138

YOU MIGHT BE WONDERING

Why Exactly Is This Awesome?

slide-139
SLIDE 139

THE MERITS OF REST

  • Easy to evolve: add new

features or elements without breaking BC

  • Easy to learn: developers can

"browse" service via link rels

  • Easy to scale up: grows well

with number of features, users and servers

  • Easy to implement: build it
  • n top of HTTP

, and profit!

  • Authentication & TLS
  • Caching & Load Balancing
  • Conditional Requests
  • Content Negotiation
slide-140
SLIDE 140

but...

slide-141
SLIDE 141

hold on, you say

slide-142
SLIDE 142

a plain HTTP-loving service does the job, you say

slide-143
SLIDE 143

surely, there is a merit to REST beyond extensibility, you ask

slide-144
SLIDE 144

nope

slide-145
SLIDE 145

"REST is software design on the scale of decades: every detail is intended to promote software longevity and independent evolution. Many of the constraints are directly opposed to short-term efficiency. Unfortunately, people are fairly good at short-term design, and usually awful at long-term design." Roy Fielding

slide-146
SLIDE 146

"Most of REST's constraints are focused on preserving independent evolvability over time, which is only measurable on the scale of years. Most developers simply don't care what happens to their product years after it is deployed, or at least they expect to be around to rewrite it when such change occurs." Roy Fielding

slide-147
SLIDE 147

FURTHER READING

  • Ryan Tomayko

How I Explained REST to my Wife http://tomayko.com/writings/rest-to-my-wife

  • Jim Webber, Savas Parastatidis & Ian Robinson

How to GET a Cup of Coffee http://www.infoq.com/articles/webber-rest-workflow

  • Roy Thomas Fielding

Architectural Styles and the Design of Network-based Software Architectures http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

slide-148
SLIDE 148

BOOKS ON REST

  • Jim Webber, Savas Parastatidis, Ian Robinson

REST in Practice ISBN: 978-0596805821

  • Subbu Allamaraju

RESTful Web Services Cookbook ISBN: 978-0596801687

  • Leonard Richardson, Sam Ruby

RESTful Web Services ISBN: 978-0596529260

slide-149
SLIDE 149

Te End

slide-150
SLIDE 150

Questions?

slide-151
SLIDE 151

THANK YOU!

This was http://munich2012.drupal.org/node/2673 by @dzuelke Send me questions or hire us: david.zuelke@bitextender.com