Your SlideShare is downloading. ×
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Usable Rest APIs by Javier Ramirez at London Ruby User Group
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Usable Rest APIs by Javier Ramirez at London Ruby User Group

2,902

Published on

With the adoption of REST, the proliferation of smartphones and tablets, and the second coming of JavaScript, exposing our applications as a service is now more important than ever. …

With the adoption of REST, the proliferation of smartphones and tablets, and the second coming of JavaScript, exposing our applications as a service is now more important than ever.

Rails or Sinatra make really easy to create a (kinda) RESTful API but, in many occassions, these APIs are designed without really thinking on the developers that will have to use them.

I want to talk about some of the points that can help making your API more developer-friendly. Some of the areas I’ll cover will be discoverability, authentication, headers, formats, parameters, documentation and tools.

Talk delivered at London Ruby User Group on 12/12/2011

Published in: Technology
2 Comments
6 Likes
Statistics
Notes
No Downloads
Views
Total Views
2,902
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
19
Comments
2
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. usable REST APIs{"links":[ {"rel":"author", "uri":"http://javier-ramirez.com"}, {"rel":"work", "uri":"http://aspgems.com"}, {"rel":"blog", "uri":"http://formatinternet.com"}, {"rel":"twittEr", "uri":"http//twitter.com/supercoco9"}]}
  • 2. 1996
  • 3. 1995
  • 4. 1996
  • 5. 1994
  • 6. 2001
  • 7. 1999
  • 8. 2004
  • 9. Web usability is anapproach to make web sites easy to use for an end-user, without the requirement that any specialized training be undertaken.[
  • 10. LearnabilityEfficIeNcyMemorabiliTyErrorsSatisfActiOn
  • 11. I want YOU to makea (REST) API
  • 12. REST in a nutshellclient server stateless layered and cacheableResources Resource Identifiers Resource metadataUniform interface operations Representations Representation metadataOptionally: code on demand
  • 13. making a REST API with Rails? easy
  • 14. BASIC WEB/apifunctionality IN RAILS
  • 15. CohesionpleasE
  • 16. separation of concerns
  • 17. SUCCESS consistently fail consistently
  • 18. expose ONLY WHAT IS Strictlynecessary
  • 19. resources are not models
  • 20. Aggregation/ composition Multiple representations
  • 21. Multiple consumers
  • 22. All your FORMATare belong to us
  • 23. > curl -d "login=ficticious_user@invoicefu.com&password=keepdreaming" https://invoicefu.com/api/session?format=json{"user":{"id":108,"name":"Nicolas Carroll","email":"ficticioususer@invoicefu.com","locale":"en","twitter_nickname":null,"facebook_uid":null,"facebook_nickname":null,"api_key":"dbd349b30b6d9fde97b01b827e6be5ed1e4fbe72","links":[{"rel":"session","uri":"https://invoicefu.com/api/session","methods":"GET,POST,DESTROY"},"rel":"account","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake","methods":"GET,PUT"},"rel":"clients","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake/clients","methods":"GET,POST"},{"rel":"new_client","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake/clients/new","methods":"GET"},{"rel":"invoices","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake/invoices","methods":"GET,POST"},{"rel":"new_invoice","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake/invoices/new","methods":"GET"},{"rel":"proformas","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake/proformas","methods":"GET,POST"},{"rel":"new_proforma","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake/proformas/new","methods":"GET"}]}}
  • 24. can I haz cat readable anzwa> curl -d "login=ficticioususer@invoicefu.com&password=yeahyeah" "https://invoicefu.com/api/session?&format=xml<?xml version="1.0" encoding="UTF-8"?><user> <id>108</id> <name>Nicolas Carroll</name> <email>user000007@invoicefu.com</email> <locale>en</locale> <twitter-nickname nil="true"></twitter-nickname> <facebook-uid nil="true"></facebook-uid> <facebook-nickname nil="true"></facebook-nickname> <api-key>dbd349b30b6d9fde97b01b827e6be5ed1e4fbe72</api-key> <links> <link> <rel>session</rel> <uri>https://invoicefu-localhost.com/api/session</uri> <methods>GET,POST,DESTROY</methods> </link> <link> <rel>account</rel> <uri>https://invoicefu-localhost.com/api/accounts/108-cole-mertz-fake</uri> <methods>GET,PUT</methods> </link> <link> <rel>clients</rel> <uri>https://invoicefu-localhost.com/api/accounts/108-cole-mertz-fake/clients</uri> <methods>GET,POST</methods> </link> <link> <rel>new_client</rel> <uri>https://invoicefu-localhost.com/api/accounts/108-cole-mertz-fake/clients/new</uri> <methods>GET</methods> </link> (…) </links></user>
  • 25. Accept: application/vnd.aspgems.invoicefu.v1.xml THE ACCEPT HEADERHTTP/REST Standard Not everyone Less obviousUnambiguous supports headers Harder to useResources != or custom types Non standard content-Representations typesVersion as you need it Skips HTTP server logs
  • 26. templates for new resources> curl "https://invoicefu.com/api/v1/accounts/108-cole-mertz-fake/invoices/new?api_key=ddd349b30b6d9fde97b01b827e6be5ed1e4fbe72&format=json"{"invoice":{"number":"2011/30","issued_on":"2011-12-12","proforma_id":null,"notes":null,"footer":null,"locale":"en","currency_code":"USD","currency_symbol":"$","ac_name":"Cole-Mertz#FAKE","ac_company_number_name":"Companynumber","ac_company_number":"25465828K","ac_tax_number_name":"VATNumber","ac_tax_number":"ES25464828k","ac_address":"234 brecknockroad","ac_city":"london","ac_province":null,"ac_postal_code":"n18 5bq","ac_country_name":"UnitedKingdom","cl_email":null,"cl_name":null,"cl_company_number_name":null,"cl_company_number":null,"cl_tax_number_name":null,"cl_tax_number":null,"cl_address":null,"cl_city":null,"cl_province":null,"cl_postal_code":null,"cl_country_name":null,"invoice_lines":[],"discount_percent":null,"tax_lines":[{"name":"TVA","signed_percent":"19.6"}],"paid":"0.0","links":[{"rel":"payments","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake/invoices//payments","methods":"POST"},{"rel":"account","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake","methods":"GET,PUT"},{"rel":"client","uri":null,"methods":"GET,PUT,DELETE"},{"rel":"proforma","uri":null,"methods":"GET,PUT,DELETE"},{"rel":"pdf","uri":null,"methods":"GET"},{"rel":"invoices","uri":"https://invoicefu.com/api/accounts/108-cole-mertz-fake/invoices","methods":"GET,POST"}]}}j
  • 27. EASy To FIND
  • 28. > curl https://invoicefu.com?format=xml (or curl -H "Accept: application/xml" "https://invoicefu.com")<?xml version="1.0" encoding="UTF-8"?><invoicefu> <links> <link> <rel>session</rel> <uri>https://invoicefu.com/api/session</uri> <methods>POST.DELETE</methods> </link> <link> <rel>countries</rel> <uri>https://invoicefu.com/api/countries</uri> <methods>GET</methods> </link> <link> <rel>api_v1</rel> <uri>https://invoicefu.com/api/session?api_version=1</uri> <methods>POST.DELETE</methods> </link> <link> <rel>xml_representation</rel> <uri>https://invoicefu.com/api/session?format=xml</uri> <methods>POST.DELETE</methods> </link> <link> <rel>json_representation</rel> <uri>https://invoicefu.com/api/session?format=json</uri> <methods>POST.DELETE</methods> </link> <link> <rel>strict_parameters</rel> <uri>https://invoicefu.com/api/session?strict=true</uri> <methods>POST.DELETE</methods> </link> </links>
  • 29. > curl -d "login=ficticioususer@invoicefu.com&password=yeahyeah" "https://invoicefu.com/api/session?&format=xml<?xml version="1.0" encoding="UTF-8"?><user> <id>108</id> <name>Nicolas Carroll</name> <email>user000007@invoicefu.com</email> <locale>en</locale> <twitter-nickname nil="true"></twitter-nickname> <facebook-uid nil="true"></facebook-uid> <facebook-nickname nil="true"></facebook-nickname> <api-key>dbd349b30b6d9fde97b01b827e6be5ed1e4fbe72</api-key> <links> <link> <rel>session</rel> <uri>https://invoicefu-localhost.com/api/session</uri> <methods>GET,POST,DESTROY</methods> </link> <link> <rel>account</rel> <uri>https://invoicefu-localhost.com/api/accounts/108-cole-mertz-fake</uri> <methods>GET,PUT</methods> </link> <link> <rel>clients</rel> <uri>https://invoicefu-localhost.com/api/accounts/108-cole-mertz-fake/clients</uri> <methods>GET,POST</methods> </link> <link> <rel>new_client</rel> <uri>https://invoicefu-localhost.com/api/accounts/108-cole-mertz-fake/clients/new</uri> <methods>GET</methods> </link> <link> <rel>invoices</rel> <uri>https://invoicefu-localhost.com/api/accounts/108-cole-mertz-fake/invoices</uri> <methods>GET,POST</methods> </link> (…) </links></user>
  • 30. BASIC ACCESS AUTHENTICATION authenticate_or_request_with_http_basic do |login, password| User.find_by_login_and_password login, password endUser and password must be passed every timeTOKENDigest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )User.find_by_login_and_api_key( params[:login], params[:api_key] )Client can send it as a parameter or as a headerOAUTHDepends on third party librariesRequires initial registration of client and more integration
  • 31. Performance
  • 32. params & debug
  • 33. > curl "https://invoicefu.com/api/accounts/108-cole-mertz-fake/invoices/new?api_key=ddd349b30b6d9fde97b01b827e6be5ed1e4fbe72&format=xml&debug=1"<?xml version="1.0" encoding="UTF-8"?><errors> <error>extra params found: debug. Allowed params are:account_id,client_id,invoice_id,proforma_id</error></errors>> curl "https://invoicefu.com/api/accounts/108-cole-mertz-fake/invoices/new?api_key=ddd349b30b6d9fde97b01b827e6be5ed1e4fbe72&format=xml&debug=1&strict=false"<?xml version="1.0" encoding="UTF-8"?><invoice> <number>2011/30</number> <issued-on>2011-12-11</issued-on> <proforma-id nil="true"></proforma-id> (...) <links> (...) <link> <rel>invoices</rel> <uri>https://invoicefu-localhost.com/api/accounts/108-cole-mertz-fake/invoices</uri> <methods>GET,POST</methods> </link> </links></invoice>
  • 34. helping your users WADLjson schema
  • 35. { <?xml version="1.0"?> "name":"Product", <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" "properties":{ xsi:schemaLocation="http://wadl.dev.java.net/2009/02 wadl.xsd" "id":{ xmlns:tns="urn:yahoo:yn" "type":"number", xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:yn="urn:yahoo:yn" "description":"Product identifier", xmlns:ya="urn:yahoo:api" "required":true xmlns="http://wadl.dev.java.net/2009/02"> }, <grammars> "name":{ <include "description":"Name of the href="NewsSearchResponse.xsd"/>product", <include "type":"string", href="Error.xsd"/> "required":true </grammars> }, "price":{ <resources base="http://api.search.yahoo.com/NewsSearchService/V1/"> <resource path="newsSearch"> "required":true, <method name="GET" id="search"> "type": "number", <request> "minimum":0, <param name="appid" type="xsd:string" "required":true style="query" required="true"/> 22 }, <param name="type" style="query" default="all"> "tags":{ <option value="all"/> "type":"array", <option value="any"/> "items":{ <option value="phrase"/> "type":"string" </param> } <param name="start" style="query" type="xsd:int" default="1"/> <param name="language" style="query" type="xsd:string"/> } </request> }, <response status="200"> "links":[ <representation mediaType="application/xml" { element="yn:ResultSet"/> "rel":"full", </response> "href":"{id}" <response status="400"> }, <representation mediaType="application/xml" { element="ya:Error"/> "rel":"comments", </response> "href":"comments/?id={id}" </method> </resource> } </resources> ] } </application>
  • 36. toolscurlHurlHttpartyrestclient
  • 37. apigee

×