Date post: | 13-Jan-2015 |
Category: |
Technology |
Upload: | tomek-cejner |
View: | 2,294 times |
Download: | 1 times |
DESIGNING BEAUTIFULREST APIs
@tomekcejner
THE PRESENTER
THE PRESENTERTOMEK [email protected]
THE PRESENTERTOMEK [email protected]
FASHION
WHAT REST MEANS
NO FRAMEWORKS
APPLICATIONS
APPLICATIONSGOING OPEN
APPLICATIONSGOING OPENGOING BIG
SOA
LOOSE COUPLING
LOOSE COUPLINGSMALLER CODEBASE
LOOSE COUPLINGSMALLER CODEBASE
REUSABILITY
WEB SERVICES
WORLDS BIGGEST APP EVER
WORLD WIDE WEB
WHAT IS REST?
A PROTOCOL?
A PROTOCOL?NO
A SPECIFICATION?
A SPECIFICATION?NO
ARCHITECTURAL STYLE
ROY T. FIELDINGPHD DISSERTATION
http://www.w3.org/Protocols/rfc2616/rfc2616.html
BUILDING ARCHITECTURE
BUILDING ARCHITECTUREFROM SCRATCH
BUILDING ARCHITECTUREFROM SCRATCHFROM WHOLE
CONSTRAINTS
CONSTRAINTSCLIENT-SERVER
CONSTRAINTSCLIENT-SERVER
STATELESS
CONSTRAINTSCLIENT-SERVER
STATELESSCACHEABLE
CONSTRAINTSCLIENT-SERVER
STATELESSCACHEABLE
UNIFORM INTERFACE
RESOURCE
URI
http://www.example.com/blogs/423/entries/12340 http://www.example.com/sales/2004/Q4http://www.example.com/bugs/by-state/open
URI
http://api.example.com/places/42.089199,93.076172http://api.example.com/color-blends/yellow;blue
URI
http://api.example.com/items?price_min=0&price_max=599
URI
http://api.example.com/auctions/239841/cancel
URI
http://api.example.com/auctions/239841/cancel
RICHARDSON MATURITY MODEL
http://www.crummy.com/writing/speaking/2008-QCon/act3.html
LEVEL 0
LEVEL 0HELL
POST /auctionServiceAPIEndpoint HTTP/1.1
<query> <params> <name>Macbook Air</name> <price_from>0</price_from> <price_to>1000</price_to> </params></query>
HTTP/1.1 200 OK
<items> <item> <id>123</id> <name>Macbook Air</name>
<price>499</price> <condition>NEW</condition> </item></items>
LEVEL 1
LEVEL 1URI
POST /auctions/1234/read
POST /auctions/1234/readGET /auctions/1234/read
POST /auctions/1234/readGET /auctions/1234/readPOST /auctions/create
POST /auctions/1234/readGET /auctions/1234/readPOST /auctions/createPOST /auctions/1234/update
LEVEL 2HTTP
/auctions
/auctions/auctions/1234
GET
GETPOST
GETPOSTPUT
GETPOSTPUT
DELETE
GETPOSTPUT
DELETEHEAD
GETPOSTPUT
DELETEHEAD
OPTIONS
GETPOSTPUT
DELETEHEAD
OPTIONSPATCH
GET
GET /auctions
GET /auctionsGET /auctions/1234
GET /auctionsGET /auctions/1234GET /auctions?search=Macbook+Air
SAFE + IDEMPOTENT
TESLA MODEL SIT HAS A RESTFUL API
GET http://api.flickr.com/services/rest?method=flickr.photos.people.add&api_key=xxx&photo_id=yyy&user_id=zzz
DELETE
DELETE
DELETE /auctions/1234
DELETE
DELETE /auctions/1234
HTTP/1.1 204 No Content
DON’T DO THIS AT HOME
DELETE
DELETEIDEMPOTENT
DELETEIDEMPOTENT
NOT SAFE
POST
POST /items{! "name" : "Macbook Air 2010",! "condition" : "NEW",! "price" : 499}
POST /items{! "name" : "Macbook Air 2010",! "condition" : "NEW",! "price" : 499}
201 CreatedLocation: http://api.alledrogo.com/items/1235
POST
NOT IDEMPOTENTPOST
NOT IDEMPOTENTNOT SAFE
POST
PUT
PUT /items/1235
{ "name" : "Macbook Air 2010",! "condition" : "LIKE_NEW",! "price" : 498}
PUT /users/joe
{ “first_name” : “Joe”, “last_name” : “Smith”}
PUTIDEMPOTENT
NOT SAFE
POST: ID FROM SERVER
POST: ID FROM SERVERPUT: ID FROM CLIENT
OPTIONS
OPTIONSDISCOVERY
OPTIONS /users HTTP/1.1
...HTTP/1.1 204 No ContentAllow: GET, POST, PUT
/users /users/456
GET
POST
PUT
DELETE
GET ALL GET USER
CREATE NEW -
- UPDATE
DELETE ALL DELETE USER
HTTP STATUS CODES
SUCCESS
SUCCESS200 OK
SUCCESS200 OK201 CREATED
SUCCESS200 OK201 CREATED202 ACCEPTED
SUCCESS200 OK201 CREATED202 ACCEPTED204 NO CONTENT
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}
REDIRECT
REDIRECT301 MOVED PERMANENTLY
REDIRECT301 MOVED PERMANENTLY303 SEE OTHER
REDIRECT301 MOVED PERMANENTLY303 SEE OTHER304 NOT MODIFIED
REDIRECT301 MOVED PERMANENTLY303 SEE OTHER304 NOT MODIFIED307 TEMPORARY REDIRECT
USER ERROR
USER ERROR400 BAD REQUEST
USER ERROR400 BAD REQUEST401 UNAUTHORIZED
USER ERROR400 BAD REQUEST401 UNAUTHORIZED403 FORBIDDEN
405 METHOD NOT ALLOWED
409 CONFLICT
410 GONE
SERVER ERROR
SERVER ERROR500 INTERNAL SERVER ERROR
SERVER ERROR500 INTERNAL SERVER ERROR503 SERVICE UNAVAILABLE
DON’T IGNORE HTTP STATUS
http://api.flickr.com/services/rest?method=flickr.photos.people.add&api_key=xxx&photo_id=yyy&user_id=zzz
DON’T IGNORE HTTP STATUS
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
<?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
LEVEL 3
LEVEL 3HYPERMEDIA
LINKING
SELF DESCRIBED CAPABILITIES
INTERCONNECTION
PRESENTATIONXHTML
XMLATOM
...
GET /items?q=macbook+air+new{! "results" : [! ! {! ! ! "id" : 1234,! ! ! "name" : "Macbook Air 2010 LIKE NEW",! ! ! "price" : "499"! ! }! ]}
NO HYPERMEDIA
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
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"}
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"}
POST /items/1234/bids{! "amount" : 602.99}
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}
DOMAIN APPLICATION PROTOCOL
HATEOAS
HATEOASHYPERMEDIA
HATEOASHYPERMEDIA
AS
HATEOASHYPERMEDIA
ASTHE ENGINE
HATEOASHYPERMEDIA
ASTHE ENGINE
OF APPLICATION STATE
IN PRACTICE
AUCTION SERVICE - USERS
AUCTION SERVICE - USERS
doGetMyDatadoGetUserIDdoGetUserItemsdoShowUserdoShowUserPage
AUCTION SERVICE - USERS
doGetMyDatadoGetUserIDdoGetUserItemsdoShowUserdoShowUserPage
GET /users/meGET /users?name=czesioGET /users/123456/itemsGET /users/123456/detailsGET /users/123456/aboutpage
AUCTION SERVICE - MY AUCTIONS
AUCTION SERVICE - MY AUCTIONS
doGetFavouriteCategoriesdoGetFavouriteSellersdoGetMyBidItemsdoGetMyWatchItems doGetMySoldItemsdoRemoveFromWatchList
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
AUCTION SERVICE - BIDDING
AUCTION SERVICE - BIDDING
doBidItemdoRequestCancelBid
AUCTION SERVICE - BIDDING
doBidItemdoRequestCancelBid
POST /items/54321/bidsDELETE /items/54321/bids/678
BEYOND CRUD
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}
COPY
POST /items/5001/duplicate;t=37489231614874
HTTP/1.1 201 CreatedLocation: /items/5002
SNAPSHOT
PUT /items/5002
{ “name” : “MacBook Air”, “price” : 399}
HTTP/1.1 204 No Content
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}
UNDO
POST /items/5002/undo;t=92312093
HTTP/1.1 303 See OtherLocation: /items/5002
ASYNCHRONOUS OPERATION
ASYNCHRONOUS OPERATIONPOST /projects/123/tasks{ “type” : “REPORT”, “date_from” : “20130101”, “date_to” : “20130331”}
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” }, ]}
MEDIA TYPES
MEDIA TYPES
Content-Type: application/vnd.alledrogo+xml
MEDIA TYPES
Content-Type: application/vnd.alledrogo+xmlContent-Type: text/html
REST VS SOAP/RPC
REST VS SOAP/RPCCOMPLEMENT, NOT CONCURRENT
NATURE OF THE WEB
CALL IT REST
CALL IT RESTWHEN DOING IT REST
THANK YOU!