O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

POX to HATEOAS: Our Company's Journey Building a Hypermedia API

8.043 visualizações

Publicada em

We started FoxyCart.com in 2007 and soon after slapped together some XML and called it an API. As our customer base grew and third-party integrations emerged, the need for a true REST API became a priority. Beginning in 2012, we started researching best practices for modern API development. This talk will tell the story of that research and 10-months of development that followed. You'll get a look at the HAL hypermedia format along with some best practices we came up with for our problem domain of exposing our entire admin interface. We'll cover a lot. You may need a seat belt.

Publicada em: Tecnologia
  • Seja o primeiro a comentar

POX to HATEOAS: Our Company's Journey Building a Hypermedia API

  1. 1. From POX to HATEOASOur Companys Journey Building a Hypermedia API
  2. 2. Who...Luke StokesCo-Founder, Developer of FoxyCartluke.stokes@foxycart.com@lukestokeshttp://bestoked.blogspot.com
  3. 3. What...FoxyCart● ecommerce shopping cart system● Started by Brett Florio and myself in 2005/2006, incorporated in 2007.● SaaS (soon to be PaaS)● Built to integrate using your css/html (were not a CMS)● No duplication of data
  4. 4. Why...No duplication? Expose our data!POX: Plain Old XML● Confusing API actions ○ transaction_get, transaction_list, attribute_save, attribute_delete, transaction_modify, store_includes_get, etc● Confusing request/response model● Tight coupling between the client and server
  5. 5. APIs and the Internet● Middleware ($$$)● RPC● SOAP● WSDL● Web Services (the WS-* stack)Tight Coupling!Does your browser do this?
  6. 6. REST to the rescueCRUD can be standardized via HTTP methods: POST/PUT = create GET = read PATCH/PUT = update DELETE = delete(goodbye *_list, *_save, *_modify, etc methods)
  7. 7. REST to the rescueAgreed upon response codes● 1xx: Informational● 2xx: Success● 3xx: Redirection● 4xx: Client Error (You Screwed Up)● 5xx: Server Error (We Screwed Up)http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
  8. 8. But... where do we start?Whats a perfect example of a REST API?
  9. 9. What is REST anyway?Six Constraints:● Client-server● Stateless● Cacheable● Layered system● Code on demand (optional)● Uniform interface ○ Identification of resources ○ Manipulation of resources through these representations ○ Self-descriptive messages ○ Hypermedia as the engine of application state
  10. 10. REST Client Need-to-Know● Homepage● Hypermedia Format● Rel tags● Known media types (and possibly versions)● Bonus stuff: ○ ?limit=5&offset=10 ○ ?order=<field> desc (or asc) ○ ?fields=<field>,<field>,<field> ○ ?<field>=<value> ○ ?<field>=<some * partial value>
  11. 11. Whats a media type?Examples: application/json application/xml application/hal+jsonOriginally defined as MIME types (RFC 2046)Also referred to as Content-Types
  12. 12. Platform = Will Not BreakEcommerce site broken at 4am and youchanged nothing?No one wants that phone call.
  13. 13. Flexible Versioning● FOXYCART-API-VERSION header
  14. 14. Flexible Versioning● FOXYCART-API-VERSION header● Per-resource vendor specific media type: application/vnd.foxycart.com.store.v1+jsonSee: http://www.foxycart.com/blog/the-hypermedia-debate
  15. 15. Flexible Versioning● FOXYCART-API-VERSION header● Per-resource vendor specific media type: application/vnd.foxycart.com.store.v1+json● Hypermedia allows us to version via the link relation we code to.
  16. 16. Flexible Versioning● FOXYCART-API-VERSION header● Per-resource vendor specific media type: application/vnd.foxycart.com.store.v1+json● Hypermedia allows us to version via the link relation we code to.link: <https://example.com/users/2>;rel="https://example.com/rels/user"
  17. 17. Flexible Versioning● FOXYCART-API-VERSION header● Per-resource vendor specific media type: application/vnd.foxycart.com.store.v1+json● Hypermedia allows us to version via the link relation we code to.link: <https://example.com/users/2>;rel="https://example.com/rels/user"link: <https://example.com/customers/2>;rel="https://example.com/rels/customer"
  18. 18. Flexible VersioningHeader: FOXYCART-API-VERSION: 1Add "awesome_sauce" field:... "store_name":"My Store", "awesome_sauce":"pixie dust", "store_domain":"example",...Additions? No problem!
  19. 19. Flexible VersioningHeader: FOXYCART-API-VERSION: 1Remove "awesome_sauce" field...Uh Oh.Option 1: rel="https://example.com/store_v2"Option 2: FOXYCART-API-VERSION: 2
  20. 20. XML Accepts HeaderHEADERS: Array( [0] => Accept: application/hal+xml [1] => FOXYCART-API-VERSION: 1)curl -X GET -H "Accept: application/hal+xml" -H"FOXYCART-API-VERSION: 1" https://api-sandbox.foxycart.com/
  21. 21. Next...?<link rel="self" href="https://api-sandbox.foxycart.com/" title="Your APIstarting point."/><link rel="https://api.foxycart.com/rels/create_client" href="https://api-sandbox.foxycart.com/clients" title="Create a client via POST."/>HATEOAS:Hypermedia as the Engine ofApplication State
  22. 22. Next...? OPTIONScurl -i -X OPTIONS -H "Authorization: Bearer cae3c0c261fc71512428d612c1d2fd2a" -H "FOXYCART-API-VERSION: 1" -H "Accept: application/hal+xml""https://api-sandbox.foxycart.com/stores/2"HTTP/1.1 200 OK..Allow: HEAD,GET,PUT,PATCH,DELETE...
  23. 23. Next...? POST: /clientsHEADERS: Array( [0] => Accept: application/hal+xml [1] => FOXYCART-API-VERSION: 1)curl -X POST -H "Accept: application/hal+xml" -H"FOXYCART-API-VERSION: 1" https://api-sandbox.foxycart.com/clients
  24. 24. Error HandlingHTTP/1.1 400 Bad RequestDate: Fri, 30 Mar 2012 21:39:50 GMTConnection: closecache-control: private, must-revalidateContent-Type: application/vnd.error+xmlContent-Length: 546https://github.com/blongden/vnd.error
  25. 25. Error Handling<errors xml:lang="en"> <error logref=42> <message>Validation failed</message> <link rel=help href=http://... title=Error information/> <link rel=describes href=http://... title=Errordescription/> </error></errors>
  26. 26. Examples!Lets take a look at the HAL Browser!Hal Talk:http://haltalk.herokuapp.com/explorer/hal_browser.html#/Foxy Cart:http://wiki.foxycart.com/v/0.0.0/hypermedia_apihttps://api-sandbox.foxycart.com/hal-browser/hal_browser.html#/https://api-sandbox.foxycart.com/hal-browser/
  27. 27. Whats all this token stuff?* image credit: http://www.ibm.com/developerworks/library/x-androidfacebookapi/
  28. 28. OAuth 2.0 - Why Bother?Remember: Platform as a service!● Hosted solutions● Hosted CMS● Self-hosted on a development platformSimplify where we can:● If you created it, you get full access to it and we can skip the OAuth Dance
  29. 29. Client Code$resp = $client->get( $api_home_page, null, $display->getHeaders());$display->displayResult(Home Page,$client);$useful_links[create_client] = $client->getLink(create_client);$resp = $client->post( $useful_links[create_client], $data, $display->getHeaders());
  30. 30. REST is easy, right? (Nope)● Should every resource have a custom media type?● How should Hypermedia be represented in JSON (Collection+JSON, HAL, Siren, etc)?● Link header exclusively or links as part of the body?● To embedded sub resources?● PATCH/PUT or POST? (X-HTTP-Method- Override)● Where to put the version number?
  31. 31. REST is easy, right? (Nope)● Include the full resource response when creating or use a 204?● How do you avoid one PATCH stomping another? ○ ETags and Preconditions ○ "If-None-Match: W/"9f55f4d0f19b152a6e7c6ddeb4107e486fd7727c"" ○ "If-Modified-Since: Wed, 15 Feb 2012 12:53:52 -0800"● How do you make hypermedia useful to the client and end user?● Forms?
  32. 32. YOU NEED TESTS!Functional tests are critical● Ensures your changes havent broken anything old or new● Speeds up prototypingTests are NOT a substitute for your eyeballs
  33. 33. The FutureReliable platformsConsistent functionalityKnown, shared resourcesNotes:http://bestoked.blogspot.com/2012/02/restful-resources-required-reading.htmlhttp://wiki.foxycart.com/v/0.0.0/hypermedia_api

×