Top Banner
DESIGNING BEAUTIFUL REST APIs @tomekcejner
175

Designing beautiful REST APIs

Jan 13, 2015

Download

Technology

Tomek Cejner

Presented on 4Developers 2013 (12th April).
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Designing beautiful REST APIs

DESIGNING BEAUTIFULREST APIs

@tomekcejner

Page 2: Designing beautiful REST APIs

THE PRESENTER

Page 5: Designing beautiful REST APIs

FASHION

Page 6: Designing beautiful REST APIs

WHAT REST MEANS

Page 7: Designing beautiful REST APIs

NO FRAMEWORKS

Page 8: Designing beautiful REST APIs

APPLICATIONS

Page 9: Designing beautiful REST APIs

APPLICATIONSGOING OPEN

Page 10: Designing beautiful REST APIs

APPLICATIONSGOING OPENGOING BIG

Page 11: Designing beautiful REST APIs

SOA

Page 12: Designing beautiful REST APIs

LOOSE COUPLING

Page 13: Designing beautiful REST APIs

LOOSE COUPLINGSMALLER CODEBASE

Page 14: Designing beautiful REST APIs

LOOSE COUPLINGSMALLER CODEBASE

REUSABILITY

Page 15: Designing beautiful REST APIs

WEB SERVICES

Page 16: Designing beautiful REST APIs
Page 17: Designing beautiful REST APIs

WORLDS BIGGEST APP EVER

Page 18: Designing beautiful REST APIs

WORLD WIDE WEB

Page 19: Designing beautiful REST APIs

WHAT IS REST?

Page 20: Designing beautiful REST APIs

A PROTOCOL?

Page 21: Designing beautiful REST APIs

A PROTOCOL?NO

Page 22: Designing beautiful REST APIs

A SPECIFICATION?

Page 23: Designing beautiful REST APIs

A SPECIFICATION?NO

Page 24: Designing beautiful REST APIs

ARCHITECTURAL STYLE

Page 25: Designing beautiful REST APIs

ROY T. FIELDINGPHD DISSERTATION

Page 27: Designing beautiful REST APIs
Page 28: Designing beautiful REST APIs

BUILDING ARCHITECTURE

Page 29: Designing beautiful REST APIs

BUILDING ARCHITECTUREFROM SCRATCH

Page 30: Designing beautiful REST APIs

BUILDING ARCHITECTUREFROM SCRATCHFROM WHOLE

Page 31: Designing beautiful REST APIs
Page 32: Designing beautiful REST APIs

CONSTRAINTS

Page 33: Designing beautiful REST APIs

CONSTRAINTSCLIENT-SERVER

Page 34: Designing beautiful REST APIs

CONSTRAINTSCLIENT-SERVER

STATELESS

Page 35: Designing beautiful REST APIs

CONSTRAINTSCLIENT-SERVER

STATELESSCACHEABLE

Page 36: Designing beautiful REST APIs

CONSTRAINTSCLIENT-SERVER

STATELESSCACHEABLE

UNIFORM INTERFACE

Page 37: Designing beautiful REST APIs

RESOURCE

Page 40: Designing beautiful REST APIs

URI

http://api.example.com/items?price_min=0&price_max=599

Page 43: Designing beautiful REST APIs

RICHARDSON MATURITY MODEL

http://www.crummy.com/writing/speaking/2008-QCon/act3.html

Page 44: Designing beautiful REST APIs
Page 45: Designing beautiful REST APIs
Page 46: Designing beautiful REST APIs
Page 47: Designing beautiful REST APIs
Page 48: Designing beautiful REST APIs
Page 49: Designing beautiful REST APIs
Page 50: Designing beautiful REST APIs

LEVEL 0

Page 51: Designing beautiful REST APIs

LEVEL 0HELL

Page 52: Designing beautiful REST APIs

POST /auctionServiceAPIEndpoint HTTP/1.1

<query> <params> <name>Macbook Air</name> <price_from>0</price_from> <price_to>1000</price_to> </params></query>

Page 53: Designing beautiful REST APIs

HTTP/1.1 200 OK

<items> <item> <id>123</id> <name>Macbook Air</name>

<price>499</price> <condition>NEW</condition> </item></items>

Page 54: Designing beautiful REST APIs

LEVEL 1

Page 55: Designing beautiful REST APIs

LEVEL 1URI

Page 56: Designing beautiful REST APIs

POST /auctions/1234/read

Page 57: Designing beautiful REST APIs

POST /auctions/1234/readGET /auctions/1234/read

Page 58: Designing beautiful REST APIs

POST /auctions/1234/readGET /auctions/1234/readPOST /auctions/create

Page 59: Designing beautiful REST APIs

POST /auctions/1234/readGET /auctions/1234/readPOST /auctions/createPOST /auctions/1234/update

Page 60: Designing beautiful REST APIs

LEVEL 2HTTP

Page 61: Designing beautiful REST APIs

/auctions

Page 62: Designing beautiful REST APIs

/auctions/auctions/1234

Page 63: Designing beautiful REST APIs

GET

Page 64: Designing beautiful REST APIs

GETPOST

Page 65: Designing beautiful REST APIs

GETPOSTPUT

Page 66: Designing beautiful REST APIs

GETPOSTPUT

DELETE

Page 67: Designing beautiful REST APIs

GETPOSTPUT

DELETEHEAD

Page 68: Designing beautiful REST APIs

GETPOSTPUT

DELETEHEAD

OPTIONS

Page 69: Designing beautiful REST APIs

GETPOSTPUT

DELETEHEAD

OPTIONSPATCH

Page 70: Designing beautiful REST APIs

GET

Page 71: Designing beautiful REST APIs
Page 72: Designing beautiful REST APIs

GET /auctions

Page 73: Designing beautiful REST APIs

GET /auctionsGET /auctions/1234

Page 74: Designing beautiful REST APIs

GET /auctionsGET /auctions/1234GET /auctions?search=Macbook+Air

Page 75: Designing beautiful REST APIs

SAFE + IDEMPOTENT

Page 76: Designing beautiful REST APIs
Page 77: Designing beautiful REST APIs

TESLA MODEL SIT HAS A RESTFUL API

Page 78: Designing beautiful REST APIs
Page 80: Designing beautiful REST APIs

DELETE

Page 81: Designing beautiful REST APIs

DELETE

DELETE /auctions/1234

Page 82: Designing beautiful REST APIs

DELETE

DELETE /auctions/1234

HTTP/1.1 204 No Content

Page 83: Designing beautiful REST APIs

DON’T DO THIS AT HOME

Page 84: Designing beautiful REST APIs

DELETE

Page 85: Designing beautiful REST APIs

DELETEIDEMPOTENT

Page 86: Designing beautiful REST APIs

DELETEIDEMPOTENT

NOT SAFE

Page 87: Designing beautiful REST APIs

POST

Page 88: Designing beautiful REST APIs

POST /items{! "name" : "Macbook Air 2010",! "condition" : "NEW",! "price" : 499}

Page 89: Designing beautiful REST APIs

POST /items{! "name" : "Macbook Air 2010",! "condition" : "NEW",! "price" : 499}

201 CreatedLocation: http://api.alledrogo.com/items/1235

Page 90: Designing beautiful REST APIs

POST

Page 91: Designing beautiful REST APIs

NOT IDEMPOTENTPOST

Page 92: Designing beautiful REST APIs

NOT IDEMPOTENTNOT SAFE

POST

Page 93: Designing beautiful REST APIs

PUT

Page 94: Designing beautiful REST APIs

PUT /items/1235

{ "name" : "Macbook Air 2010",! "condition" : "LIKE_NEW",! "price" : 498}

Page 95: Designing beautiful REST APIs

PUT /users/joe

{ “first_name” : “Joe”, “last_name” : “Smith”}

Page 96: Designing beautiful REST APIs

PUTIDEMPOTENT

NOT SAFE

Page 97: Designing beautiful REST APIs

POST: ID FROM SERVER

Page 98: Designing beautiful REST APIs

POST: ID FROM SERVERPUT: ID FROM CLIENT

Page 99: Designing beautiful REST APIs

OPTIONS

Page 100: Designing beautiful REST APIs

OPTIONSDISCOVERY

Page 101: Designing beautiful REST APIs

OPTIONS /users HTTP/1.1

...HTTP/1.1 204 No ContentAllow: GET, POST, PUT

Page 102: Designing beautiful REST APIs

/users /users/456

GET

POST

PUT

DELETE

GET ALL GET USER

CREATE NEW -

- UPDATE

DELETE ALL DELETE USER

Page 103: Designing beautiful REST APIs

HTTP STATUS CODES

Page 104: Designing beautiful REST APIs

SUCCESS

Page 105: Designing beautiful REST APIs

SUCCESS200 OK

Page 106: Designing beautiful REST APIs

SUCCESS200 OK201 CREATED

Page 107: Designing beautiful REST APIs

SUCCESS200 OK201 CREATED202 ACCEPTED

Page 108: Designing beautiful REST APIs

SUCCESS200 OK201 CREATED202 ACCEPTED204 NO CONTENT

Page 109: Designing beautiful REST APIs

201 CREATEDPOST /items/1234/bids{! "amount" : 602.99}

201 CreatedLocation: http://api.alledrogo.com/items/1234/bids/100001{! "cap_amount" : 602.99,! "current_bid" : 510,! "winning" : true}

Page 110: Designing beautiful REST APIs

REDIRECT

Page 111: Designing beautiful REST APIs

REDIRECT301 MOVED PERMANENTLY

Page 112: Designing beautiful REST APIs

REDIRECT301 MOVED PERMANENTLY303 SEE OTHER

Page 113: Designing beautiful REST APIs

REDIRECT301 MOVED PERMANENTLY303 SEE OTHER304 NOT MODIFIED

Page 114: Designing beautiful REST APIs

REDIRECT301 MOVED PERMANENTLY303 SEE OTHER304 NOT MODIFIED307 TEMPORARY REDIRECT

Page 115: Designing beautiful REST APIs

USER ERROR

Page 116: Designing beautiful REST APIs

USER ERROR400 BAD REQUEST

Page 117: Designing beautiful REST APIs

USER ERROR400 BAD REQUEST401 UNAUTHORIZED

Page 118: Designing beautiful REST APIs

USER ERROR400 BAD REQUEST401 UNAUTHORIZED403 FORBIDDEN

Page 119: Designing beautiful REST APIs

http://cropp.com/404

Page 120: Designing beautiful REST APIs

405 METHOD NOT ALLOWED

Page 121: Designing beautiful REST APIs

409 CONFLICT

Page 122: Designing beautiful REST APIs

410 GONE

Page 123: Designing beautiful REST APIs

SERVER ERROR

Page 124: Designing beautiful REST APIs

SERVER ERROR500 INTERNAL SERVER ERROR

Page 125: Designing beautiful REST APIs

SERVER ERROR500 INTERNAL SERVER ERROR503 SERVICE UNAVAILABLE

Page 126: Designing beautiful REST APIs

DON’T IGNORE HTTP STATUS

Page 129: Designing beautiful REST APIs

<?xml version="1.0" encoding="utf-8" ?><rsp stat="fail"> <err code="100" msg="Invalid API Key (Key has invalid format)" /></rsp>

http://api.flickr.com/services/rest?method=flickr.photos.people.add&api_key=xxx&photo_id=yyy&user_id=zzz

HTTP/200 OK

DON’T IGNORE HTTP STATUS

Page 130: Designing beautiful REST APIs

LEVEL 3

Page 131: Designing beautiful REST APIs

LEVEL 3HYPERMEDIA

Page 132: Designing beautiful REST APIs

LINKING

Page 133: Designing beautiful REST APIs
Page 134: Designing beautiful REST APIs

SELF DESCRIBED CAPABILITIES

INTERCONNECTION

Page 135: Designing beautiful REST APIs

PRESENTATIONXHTML

XMLATOM

...

Page 136: Designing beautiful REST APIs

GET /items?q=macbook+air+new{! "results" : [! ! {! ! ! "id" : 1234,! ! ! "name" : "Macbook Air 2010 LIKE NEW",! ! ! "price" : "499"! ! }! ]}

NO HYPERMEDIA

Page 137: Designing beautiful REST APIs

GET /items?q=macbook+air+new{! "results" : [! ! {! ! ! "_links" : [! ! ! ! { "rel" : "self", "uri" : "/items/1234" },! ! ! ! { "rel" : "bids", "uri" : "/items/1234/bids" },! ! ! ! { "rel" : "highest_bid", "uri" : "/items/1234/bids?q=winning" }! ! ! ],! ! ! "name" : "Macbook Air 2010 LIKE NEW",! ! ! "price" : "499"! ! }! ]}

WITH HYPERMEDIA

Page 138: Designing beautiful REST APIs

GET /items/1234{! "_links" : [! ! { "rel" : "self", "uri" : "/items/1234" },! ! { "rel" : "bids", "uri" : "/items/1234/bids"},! ! { "rel" : "seller", "uri" : "/users/9876"}! ],! "name" : "Macbook Air 2010 LIKE NEW",! "price" : "499"}

Page 139: Designing beautiful REST APIs

GET /users/9876{! "_links" : [! ! { "rel" : "self", "uri" : "/users/9876" },! ! { "rel" : "ratings", "uri" : "/users/9876/ratings" }! ! { "rel" : "messages", "uri" : "/users/9876/messages" }! ! { "rel" : "listings", "uri" : "/users/9876/listings" }! ],! "name" : "John Doe"}

Page 140: Designing beautiful REST APIs

POST /items/1234/bids{! "amount" : 602.99}

Page 141: Designing beautiful REST APIs

POST /items/1234/bids{! "amount" : 602.99}

201 CreatedLocation: http://api.alledrogo.com/items/1234/bids/100001{! "_links" : [! ! { "rel" : "self", "uri" : "/items/1234/bids/100001" },! ! { "rel" : "item", "uri" : "/items/1234" },! ]! "cap_amount" : 602.99,! "current_bid" : 510,! "winning" : true}

Page 142: Designing beautiful REST APIs

DOMAIN APPLICATION PROTOCOL

Page 143: Designing beautiful REST APIs

HATEOAS

Page 144: Designing beautiful REST APIs

HATEOASHYPERMEDIA

Page 145: Designing beautiful REST APIs

HATEOASHYPERMEDIA

AS

Page 146: Designing beautiful REST APIs

HATEOASHYPERMEDIA

ASTHE ENGINE

Page 147: Designing beautiful REST APIs

HATEOASHYPERMEDIA

ASTHE ENGINE

OF APPLICATION STATE

Page 148: Designing beautiful REST APIs

IN PRACTICE

Page 149: Designing beautiful REST APIs

AUCTION SERVICE - USERS

Page 150: Designing beautiful REST APIs

AUCTION SERVICE - USERS

doGetMyDatadoGetUserIDdoGetUserItemsdoShowUserdoShowUserPage

Page 151: Designing beautiful REST APIs

AUCTION SERVICE - USERS

doGetMyDatadoGetUserIDdoGetUserItemsdoShowUserdoShowUserPage

GET /users/meGET /users?name=czesioGET /users/123456/itemsGET /users/123456/detailsGET /users/123456/aboutpage

Page 152: Designing beautiful REST APIs

AUCTION SERVICE - MY AUCTIONS

Page 153: Designing beautiful REST APIs

AUCTION SERVICE - MY AUCTIONS

doGetFavouriteCategoriesdoGetFavouriteSellersdoGetMyBidItemsdoGetMyWatchItems doGetMySoldItemsdoRemoveFromWatchList

Page 154: Designing beautiful REST APIs

AUCTION SERVICE - MY AUCTIONS

doGetFavouriteCategoriesdoGetFavouriteSellersdoGetMyBidItemsdoGetMyWatchItems doGetMySoldItemsdoRemoveFromWatchList

GET /users/me/favorites/categoryGET /users/me/favorites/sellersGET /users/me/bidsGET /users/me/items/watchingGET /users/me/items/soldDELETE /users/me/items/watching/1

Page 155: Designing beautiful REST APIs

AUCTION SERVICE - BIDDING

Page 156: Designing beautiful REST APIs

AUCTION SERVICE - BIDDING

doBidItemdoRequestCancelBid

Page 157: Designing beautiful REST APIs

AUCTION SERVICE - BIDDING

doBidItemdoRequestCancelBid

POST /items/54321/bidsDELETE /items/54321/bids/678

Page 158: Designing beautiful REST APIs

BEYOND CRUD

Page 159: Designing beautiful REST APIs

COPYGET /items/5001

HTTP/1.1 200 OK{ “_links” : [ { “rel” : “self”, “href” : “/items/5001” }, { “rel” : “duplicate”, “href” : “/items/5001/duplicate;t=37489231614874” } ], “name” : “MacBook Air”, “price” : 599}

Page 160: Designing beautiful REST APIs

COPY

POST /items/5001/duplicate;t=37489231614874

HTTP/1.1 201 CreatedLocation: /items/5002

Page 161: Designing beautiful REST APIs

SNAPSHOT

PUT /items/5002

{ “name” : “MacBook Air”, “price” : 399}

HTTP/1.1 204 No Content

Page 162: Designing beautiful REST APIs

SNAPSHOTGET /items/5002

{ “_links” : [ { “rel” : “self”, “href” : “/items/5002” }, { “rel” : “duplicate”, “href” : “/items/5002/duplicate;t=98435943498” }, { “rel” : “previous”, “href” : “/items/5002/s1” }, { “rel” : “undo”, “href” : “/items/5002/undo;t=92312093” }, ], “name” : “MacBook Air”, “price” : 599}

Page 163: Designing beautiful REST APIs

UNDO

POST /items/5002/undo;t=92312093

HTTP/1.1 303 See OtherLocation: /items/5002

Page 164: Designing beautiful REST APIs

ASYNCHRONOUS OPERATION

Page 165: Designing beautiful REST APIs

ASYNCHRONOUS OPERATIONPOST /projects/123/tasks{ “type” : “REPORT”, “date_from” : “20130101”, “date_to” : “20130331”}

Page 166: Designing beautiful REST APIs

ASYNCHRONOUS OPERATIONPOST /projects/123/tasks{ “type” : “REPORT”, “date_from” : “20130101”, “date_to” : “20130331”}

HTTP/1.1 202 Accepted{ “state” : “PENDING”, “ping-after” : “2013-04-12T17:02:32Z” “_links” : [ { “rel” : ”outcome”, “href” : “http://api.example.com/reports/882” }, ]}

Page 167: Designing beautiful REST APIs

MEDIA TYPES

Page 168: Designing beautiful REST APIs

MEDIA TYPES

Content-Type: application/vnd.alledrogo+xml

Page 169: Designing beautiful REST APIs

MEDIA TYPES

Content-Type: application/vnd.alledrogo+xmlContent-Type: text/html

Page 170: Designing beautiful REST APIs

REST VS SOAP/RPC

Page 171: Designing beautiful REST APIs

REST VS SOAP/RPCCOMPLEMENT, NOT CONCURRENT

Page 172: Designing beautiful REST APIs

NATURE OF THE WEB

Page 173: Designing beautiful REST APIs

CALL IT REST

Page 174: Designing beautiful REST APIs

CALL IT RESTWHEN DOING IT REST

Page 175: Designing beautiful REST APIs

THANK YOU!