apis rest usables con hypermedia por javier ramirez, para codemotion

Post on 10-May-2015

2.838 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Con la adopción de REST, la proliferación de smartphones y tablets y el revival del JavaScript, exponer nuestra aplicación como un servicio es más importante que nunca. Frameworks como Rails hacen muy fácil la creación de un API (más o menos) REST, pero en muchas ocasiones estas APIs se diseñan sin pensar realmente en los desarrolladores que las va a usar. En esta charla habo sobre algunos de los puntos que pueden hacer tu API REST más amigable para desarrolladores, cubriendo áreas como el autodescubrimiento, autenticación, cabeceras, formatos, versionado, parámetros, documentación y herramientas. Aunque comparte tema (y algunas slides) con la charla de APIs usables que preparé para el grupo de Usuarios de Ruby en Londres, gran parte del material es inédito.

TRANSCRIPT

APIs REST Usables

Javier Ramírez

@supercoco9@aspgems

{"links":[ {"rel":"author", "uri":"http://javier-ramirez.com"}, {"rel":"work", "uri":"http://aspgems.com"}, {"rel":"twittEr", "uri":"http//twitter.com/supercoco9"} {"rel":"api-usable", "uri":"https//invoicefu.com"}]}*ningún gatico (ni ningún friki ansioso) ha sido dañado para hacer esta presentación

APIs RESTusableS*

edición codemotion.es

1996

1995

1996

1994

2001

La usabilidad Web es un enfoque para construir

sitios web faciles de usar para un usuario final, sin que se requiera ninguna formacion especializada'

'

LearnabilityEfficIeNcyMemorabiliTyErrorsSatisfActiOn

API “REST”

Hecha con RAILS

en lo que se

TARDA EN decir

constantinopla

separation of concerns

modelo de recursos

Autenticación y (NO) Estado

formatosversionado

múltiples consumidores

paginaciónEscalabilidad

cuotasmetadatos

cachés

Estados y gestión de erroresanalíticamonetizaciónDocumentaciónfirst class api?

…y uSaBiLidAd

BASIC ACCESS AUTHENTICATION

OAUTH

TOKEN

authenticate_or_request_with_http_basic do |login, password| User.find_by_login_and_password login, password endUser and password must be passed every time

Digest::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 header

Depends on third party libraries Requires initial registration of client and more integration

SUCCESS consistently

fail consistently

invoicefu200 OK Success!201 Created304 Not Modified401 Unauthorized404 Not Found422 Unprocessable Entity406 Not Acceptable500 Internal Server Error

huddle200 OK 201 Created202 Accepted400 Bad Request401 Unauthorized403 Forbidden404 Not Found410 Gone

twitter200 OK Success!304 Not Modified400 Bad Request401 Unauthorized403 Forbidden404 Not Found406 Not Acceptable420 Enhance Your Calm500 Internal Server Error502 Bad Gateway503 Service Unavailable

Useful Status429 Too many requests204 No Content

THE

ACCEPT

HEADER

HTTP/REST StandardUnambiguousResources != RepresentationsVersion as you need it

Not everyone supports headers or custom types.Generic content types are preferred

Less obviousHarder to useNon standard content-typesSkips HTTP server logs

Accept: application/vnd.aspgems.invoicefu.v1.xml

REST explicado por un señor que tan listo no será cuando

no usa gafasclient-server,stateless,layered,cacheable

Resources

Resource Identifiers

Resource metadata

Uniform interface

operations

Representations

Representation metadata

HATEOAS

Optionally: code on demand señor sin gafas

get, HEAD, TRACE, OPTIONS

post, put*, delete*, PATCH*

*fallbacks para clientes viejos o incompletos

INTERFAZ UNIFORME

herebe

dragons

restfest 2011

expose ONLYWHAT IS

Strictly necessary

resources are not models

Aggregation/

composition

Multiple

representations

Hypermedia

APIs descubriblesRecursos asociadosSiguientes pasosPaginación

https://invoicefu.com?

format=xml

curl -X POST "https://invoicefu.com/api/session?

format=xml&login=hello@invoicefu.com&password=YAY

<?xml version="1.0" encoding="UTF-8"?><user> <id>3</id> <name>javier ramir</name> <email>javier@formatinternet.com</email> <locale>es</locale> <twitter-nickname>supercoco9</twitter-nickname> <facebook-uid nil="true"></facebook-uid> <facebook-nickname nil="true"></facebook-nickname> <api-key>c23e830d9b092a3a801d7f49b46</api-key> <links> <link> <rel>clients</rel> <uri>https://invoicefu.com/api/accounts/3-javier-ramirez/clients</uri> <methods>GET,POST</methods> </link> <link> <rel>new_client</rel> <uri>https://invoicefu.com/api/accounts/3-javier-ramirez/clients/new</uri> <methods>GET</methods> </link>

Rob Eisenberg

<productions> <links> <link rel="self" href="..." /> <link rel="next" href="..." /> </links> <production> <name>RavenDB</name> <author>Oren Eini</author> <links> <link rel="self" href="..." /> <link rel="rels/episodes" href="..." /> </links> </production> <production> <name>Art of Speaking</name> <author>Scott Hanselman</author> <links> <link rel="self" href="..." /> <link rel="rels/episodes" href="..." /> </links> </production> <!--other productions elided--> </productions>

Mike Kelly

{ "_links": { "self": { "href": "..." } }, "title": "Real World ASP.NET MVC3", "description": "In this advanced, somewhat-opinionated...", "permitted": true, "_embedded": { "episodes": [{ "_links": { "self": { "href": "..." }, "media": [{ "type": "video/webm; codecs='vp8.0, vorbis'", "href": "..." },{ "type": "video/ogg; codecs='theora, vorbis'", "href": "..." }] }, "title": "Foundations", "description": "In this episode we talk about what it is we're doing: building our startup and getting ourselves off the ground. We take..", "released": 1306972800 }

DARREL MILLER

{ "_links" : { "self" : { "href" : "/user/95/allproductions" }, }, "name" : "Joe", "_embedded" : { "urn:tekpub:production" : [ { "_links": { "self": { "href": "/production/22" }, }, "allowed" : "true", "title" : "Rails runs rings round ReST resource representations" }, { "_links": { "self": { "href": "/production/74" }, }, "allowed" : "false", "title" : "Surfing the waves beats surfing an API" } ] }}

ACTS AS API :Filtros

URI templates

http://example.com/~{username}/ http://example.com/dictionary/{term:1}/{term} http://example.com/search{?q,lang}

> 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>

templates

for new

resources> curl "https://invoicefu.com/api/accounts/108-cole-mertz-fake/invoices/new?api_key=ddd349b30b6d9fde97b027e6be5ed1e4fbe72&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":"Company number","ac_company_number":"25465828K","ac_tax_number_name":"VAT Number","ac_tax_number":"ES25464828k","ac_address":"234 brecknock road","ac_city":"london","ac_province":null,"ac_postal_code":"n18 5bq","ac_country_name":"United Kingdom","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

Multiple consumers

All your

FORMAT

are belong

to us *even native formats

javascript revival

Cross origin

resource sharing

use the

metadata

luke

Permitir cabeceras del tiporeturn-asyncreturn-representationreturn-minimal

Devolver cabeceras útiles

Respuestas parcialeshttps://gdata.youtube.com/feeds/api/users/default/uploads?fields=entry(title,gd:comments,yt:statistics)

fields=entry[link/@rel='http://gdata.youtube.com/schemas/2007%23mobile']

Implementación en invoicefu

apigee

http://usemyapi.com

12 mayo 2012

{"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"}]}*ningún gatico (ni ningún friki ansioso) ha sido dañado para hacer esta presentación

APIs RESTusableS*

edición codemotion.es

top related