Designing beautiful REST APIs

2,937 views
2,826 views

Published on

Presented on 4Developers 2013 (12th April).

0 Comments
13 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,937
On SlideShare
0
From Embeds
0
Number of Embeds
945
Actions
Shares
0
Downloads
54
Comments
0
Likes
13
Embeds 0
No embeds

No notes for slide

Designing beautiful REST APIs

  1. 1. DESIGNING BEAUTIFUL REST APIs @tomekcejner
  2. 2. THE PRESENTER
  3. 3. THE PRESENTER TOMEK CEJNER @tomekcejner www.japko.net tomek@japko.net
  4. 4. THE PRESENTER TOMEK CEJNER @tomekcejner www.japko.net tomek@japko.net
  5. 5. FASHION
  6. 6. WHAT REST MEANS
  7. 7. NO FRAMEWORKS
  8. 8. APPLICATIONS
  9. 9. APPLICATIONS GOING OPEN
  10. 10. APPLICATIONS GOING OPEN GOING BIG
  11. 11. SOA
  12. 12. LOOSE COUPLING
  13. 13. LOOSE COUPLINGSMALLER CODEBASE
  14. 14. LOOSE COUPLINGSMALLER CODEBASE REUSABILITY
  15. 15. WEB SERVICES
  16. 16. WORLDS BIGGEST APP EVER
  17. 17. WORLD WIDE WEB
  18. 18. WHAT IS REST?
  19. 19. A PROTOCOL?
  20. 20. A PROTOCOL? NO
  21. 21. A SPECIFICATION?
  22. 22. A SPECIFICATION? NO
  23. 23. ARCHITECTURAL STYLE
  24. 24. ROY T. FIELDINGPHD DISSERTATION
  25. 25. http://www.w3.org/Protocols/rfc2616/rfc2616.html
  26. 26. BUILDING ARCHITECTURE
  27. 27. BUILDING ARCHITECTURE FROM SCRATCH
  28. 28. BUILDING ARCHITECTURE FROM SCRATCH FROM WHOLE
  29. 29. CONSTRAINTS
  30. 30. CONSTRAINTSCLIENT-SERVER
  31. 31. CONSTRAINTSCLIENT-SERVER STATELESS
  32. 32. CONSTRAINTSCLIENT-SERVER STATELESS CACHEABLE
  33. 33. CONSTRAINTS CLIENT-SERVER STATELESS CACHEABLEUNIFORM INTERFACE
  34. 34. RESOURCE
  35. 35. URIhttp://www.example.com/blogs/423/entries/12340http://www.example.com/sales/2004/Q4http://www.example.com/bugs/by-state/open
  36. 36. URIhttp://api.example.com/places/42.089199,93.076172http://api.example.com/color-blends/yellow;blue
  37. 37. URIhttp://api.example.com/items?price_min=0&price_max=599
  38. 38. URIhttp://api.example.com/auctions/239841/cancel
  39. 39. URIhttp://api.example.com/auctions/239841/cancel
  40. 40. RICHARDSON MATURITY MODEL http://www.crummy.com/writing/speaking/2008-QCon/act3.html
  41. 41. LEVEL 0
  42. 42. LEVEL 0 HELL
  43. 43. POST /auctionServiceAPIEndpoint HTTP/1.1<query> <params> <name>Macbook Air</name> <price_from>0</price_from> <price_to>1000</price_to> </params></query>
  44. 44. HTTP/1.1 200 OK<items> <item> <id>123</id> <name>Macbook Air</name> <price>499</price> <condition>NEW</condition> </item></items>
  45. 45. LEVEL 1
  46. 46. LEVEL 1 URI
  47. 47. POST /auctions/1234/read
  48. 48. POST /auctions/1234/readGET /auctions/1234/read
  49. 49. POST /auctions/1234/readGET /auctions/1234/readPOST /auctions/create
  50. 50. POST /auctions/1234/readGET /auctions/1234/readPOST /auctions/createPOST /auctions/1234/update
  51. 51. LEVEL 2 HTTP
  52. 52. /auctions
  53. 53. /auctions/auctions/1234
  54. 54. GET
  55. 55. GETPOST
  56. 56. GETPOSTPUT
  57. 57. GET POST PUTDELETE
  58. 58. GET POST PUTDELETE HEAD
  59. 59. GET POST PUT DELETE HEADOPTIONS
  60. 60. GET POST PUT DELETE HEADOPTIONS PATCH
  61. 61. GET
  62. 62. GET /auctions
  63. 63. GET /auctionsGET /auctions/1234
  64. 64. GET /auctionsGET /auctions/1234GET /auctions?search=Macbook+Air
  65. 65. SAFE + IDEMPOTENT
  66. 66. TESLA MODEL SIT HAS A RESTFUL API
  67. 67. GET http://api.flickr.com/services/rest?method=flickr.photos.people.add&api_key=xxx&photo_id=yyy&user_id=zzz
  68. 68. DELETE
  69. 69. DELETEDELETE /auctions/1234
  70. 70. DELETEDELETE /auctions/1234HTTP/1.1 204 No Content
  71. 71. DON’T DO THIS AT HOME
  72. 72. DELETE
  73. 73. DELETEIDEMPOTENT
  74. 74. DELETEIDEMPOTENT NOT SAFE
  75. 75. POST
  76. 76. POST /items{! "name" : "Macbook Air 2010",! "condition" : "NEW",! "price" : 499}
  77. 77. POST /items{! "name" : "Macbook Air 2010",! "condition" : "NEW",! "price" : 499}201 CreatedLocation: http://api.alledrogo.com/items/1235
  78. 78. POST
  79. 79. POSTNOT IDEMPOTENT
  80. 80. POSTNOT IDEMPOTENT NOT SAFE
  81. 81. PUT
  82. 82. PUT /items/1235{ "name" : "Macbook Air 2010",! "condition" : "LIKE_NEW",! "price" : 498}
  83. 83. PUT /users/joe{ “first_name” : “Joe”, “last_name” : “Smith”}
  84. 84. PUTIDEMPOTENT NOT SAFE
  85. 85. POST: ID FROM SERVER
  86. 86. POST: ID FROM SERVER PUT: ID FROM CLIENT
  87. 87. OPTIONS
  88. 88. OPTIONSDISCOVERY
  89. 89. OPTIONS /users HTTP/1.1...HTTP/1.1 204 No ContentAllow: GET, POST, PUT
  90. 90. /users /users/456 GET GET ALL GET USERPOST CREATE NEW - PUT - UPDATEDELETE DELETE ALL DELETE USER
  91. 91. HTTP STATUS CODES
  92. 92. SUCCESS
  93. 93. SUCCESS200 OK
  94. 94. SUCCESS200 OK201 CREATED
  95. 95. SUCCESS200 OK201 CREATED202 ACCEPTED
  96. 96. SUCCESS200 OK201 CREATED202 ACCEPTED204 NO CONTENT
  97. 97. 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}
  98. 98. REDIRECT
  99. 99. REDIRECT301 MOVED PERMANENTLY
  100. 100. REDIRECT301 MOVED PERMANENTLY303 SEE OTHER
  101. 101. REDIRECT301 MOVED PERMANENTLY303 SEE OTHER304 NOT MODIFIED
  102. 102. REDIRECT301 MOVED PERMANENTLY303 SEE OTHER304 NOT MODIFIED307 TEMPORARY REDIRECT
  103. 103. USER ERROR
  104. 104. USER ERROR400 BAD REQUEST
  105. 105. USER ERROR400 BAD REQUEST401 UNAUTHORIZED
  106. 106. USER ERROR400 BAD REQUEST401 UNAUTHORIZED403 FORBIDDEN
  107. 107. http://cropp.com/404
  108. 108. 405 METHOD NOT ALLOWED
  109. 109. 409 CONFLICT
  110. 110. 410 GONE
  111. 111. SERVER ERROR
  112. 112. SERVER ERROR500 INTERNAL SERVER ERROR
  113. 113. SERVER ERROR500 INTERNAL SERVER ERROR503 SERVICE UNAVAILABLE
  114. 114. DON’T IGNORE HTTP STATUS
  115. 115. DON’T IGNORE HTTP STATUShttp://api.flickr.com/services/rest?method=flickr.photos.people.add&api_key=xxx&photo_id=yyy&user_id=zzz
  116. 116. DON’T IGNORE HTTP STATUShttp://api.flickr.com/services/rest?method=flickr.photos.people.add&api_key=xxx&photo_id=yyy&user_id=zzzHTTP/200 OK
  117. 117. DON’T IGNORE HTTP STATUShttp://api.flickr.com/services/rest?method=flickr.photos.people.add&api_key=xxx&photo_id=yyy&user_id=zzzHTTP/200 OK<?xml version="1.0" encoding="utf-8" ?><rsp stat="fail"> <err code="100" msg="Invalid API Key (Key has invalid format)" /></rsp>
  118. 118. LEVEL 3
  119. 119. LEVEL 3HYPERMEDIA
  120. 120. LINKING
  121. 121. SELF DESCRIBED CAPABILITIESINTERCONNECTION
  122. 122. PRESENTATION XHTML XML ATOM ...
  123. 123. NO HYPERMEDIAGET /items?q=macbook+air+new{! "results" : [! ! {! ! ! "id" : 1234,! ! ! "name" : "Macbook Air 2010 LIKE NEW",! ! ! "price" : "499"! ! }! ]}
  124. 124. WITH HYPERMEDIAGET /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"! ! }! ]}
  125. 125. 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"}
  126. 126. 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"}
  127. 127. POST /items/1234/bids{! "amount" : 602.99}
  128. 128. 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}
  129. 129. DOMAIN APPLICATION PROTOCOL
  130. 130. HATEOAS
  131. 131. HATEOASHYPERMEDIA
  132. 132. HATEOASHYPERMEDIA AS
  133. 133. HATEOASHYPERMEDIA ASTHE ENGINE
  134. 134. HATEOAS HYPERMEDIA AS THE ENGINEOF APPLICATION STATE
  135. 135. IN PRACTICE
  136. 136. AUCTION SERVICE - USERS
  137. 137. AUCTION SERVICE - USERSdoGetMyDatadoGetUserIDdoGetUserItemsdoShowUserdoShowUserPage
  138. 138. AUCTION SERVICE - USERSdoGetMyData GET /users/medoGetUserID GET /users?name=czesiodoGetUserItems GET /users/123456/itemsdoShowUser GET /users/123456/detailsdoShowUserPage GET /users/123456/aboutpage
  139. 139. AUCTION SERVICE - MY AUCTIONS
  140. 140. AUCTION SERVICE - MY AUCTIONSdoGetFavouriteCategoriesdoGetFavouriteSellersdoGetMyBidItemsdoGetMyWatchItemsdoGetMySoldItemsdoRemoveFromWatchList
  141. 141. AUCTION SERVICE - MY AUCTIONSdoGetFavouriteCategories GET /users/me/favorites/categorydoGetFavouriteSellers GET /users/me/favorites/sellersdoGetMyBidItems GET /users/me/bidsdoGetMyWatchItems GET /users/me/items/watchingdoGetMySoldItems GET /users/me/items/solddoRemoveFromWatchList DELETE /users/me/items/watching/1
  142. 142. AUCTION SERVICE - BIDDING
  143. 143. AUCTION SERVICE - BIDDINGdoBidItemdoRequestCancelBid
  144. 144. AUCTION SERVICE - BIDDINGdoBidItem POST /items/54321/bidsdoRequestCancelBid DELETE /items/54321/bids/678
  145. 145. BEYOND CRUD
  146. 146. COPYGET /items/5001HTTP/1.1 200 OK{ “_links” : [ { “rel” : “self”, “href” : “/items/5001” }, { “rel” : “duplicate”, “href” : “/items/5001/duplicate;t=37489231614874” } ], “name” : “MacBook Air”, “price” : 599}
  147. 147. COPYPOST /items/5001/duplicate;t=37489231614874HTTP/1.1 201 CreatedLocation: /items/5002
  148. 148. SNAPSHOTPUT /items/5002{ “name” : “MacBook Air”, “price” : 399}HTTP/1.1 204 No Content
  149. 149. 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}
  150. 150. UNDOPOST /items/5002/undo;t=92312093HTTP/1.1 303 See OtherLocation: /items/5002
  151. 151. ASYNCHRONOUS OPERATION
  152. 152. ASYNCHRONOUS OPERATIONPOST /projects/123/tasks{ “type” : “REPORT”, “date_from” : “20130101”, “date_to” : “20130331”}
  153. 153. 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” }, ]}
  154. 154. MEDIA TYPES
  155. 155. MEDIA TYPESContent-Type: application/vnd.alledrogo+xml
  156. 156. MEDIA TYPESContent-Type: application/vnd.alledrogo+xmlContent-Type: text/html
  157. 157. REST VS SOAP/RPC
  158. 158. REST VS SOAP/RPCCOMPLEMENT, NOT CONCURRENT
  159. 159. NATURE OF THE WEB
  160. 160. CALL IT REST
  161. 161. CALL IT RESTWHEN DOING IT REST
  162. 162. THANK YOU!

×