RESTful 4 all
Diego Sapriza
[email protected]@AV4TAr Como diseñar una API RESTful
sin morir en el intento.
Hi! Diego Sapriza
@AV4TAr
I’M
.
.uy
PHP.meetup.uy
DevOps.meetup.uy
“El mundo evoluciona
constantemente”
Restful api
versionamiento
recursos
status codes
autenticación
mensajes
paginación
documentación!
hypermedia (HATEOAS)
verbos
tools
Quiénes hacen
mayoritariamente
Web dev?
REpresentational State transfer
no es un estándar
Acuerdo
https://www.flickr.com/photos/124247024@N07/
Roy Fielding
escalabilidad
:(
restricciones escalabilidad
Client-Server
Stateless
Cache
Uniform Interfaces
Layered System
Code on demand (opcional)
Richardson Maturity Model
http://bit.ly/api-rmm
0: The Swamp of POX
RPC
SOBRE
HTTP
JSON
XML
html
images
0: The Swamp of POX
GET
http://srv.com/addin/auto-‐harvest/end-‐job/:id/
errors/:errors_messages
http://srv.com/addin/auto-‐harvest/start-‐job/:id
Richardson Maturity Model
http://bit.ly/api-rmm
Uniform Interfaces
• Identificación recursos.
• Manipulación de recursos a través de su
representación.
• Mensajes auto-descriptivos.
• Hypermedia como motor del estado de la
aplicación (HATEOAS).
1: RECURSOS
tienen una URI
mapean entidad/es
sustantivos
uri
scheme:hierarchical part[?query][#fragment]
telnet://192.168.1.1
urn:isbn:978-1-449-3150-9
mailto:
[email protected]
https://api.twilio.com/2010-‐04-‐01
identificación
/recurso/:id
/recurso/:id/:acción
!
/?r=recurso&id=:id
/?r=recurso&id=:id&a=:acción
colecciones
/recursos
/recursos/:id
/recursos/:id?pagina=:n&limite=100
Richardson Maturity Model
Uniform Interfaces
• Identificación recursos.
• Manipulación de recursos a través de su
representación.!
• Mensajes auto-descriptivos.
• Hypermedia como motor del estado de la
aplicación (HATEOAS).
Representación
HTTP verbs
Get Post Put Delete
Patch Options Head
Trace Connect
http://bit.ly/http-‐request-‐methods
crudhttpCREATEPOSTREADGETUPDATEPUTDELETEDELETE métodoseguroidempotentecachableGETHEADPOSTPUTDELETE GET/personasObtener
lista
de
personasPOST/personasAgregar
una
personaDELETE/personas/:idEliminar
una
personaGET/personas/:idObtener
una
personaPUT/personas/:idActualizar
una
personaGET/personas/:id/contactosObtener
los
contactos
de
una
personaPOST/personas/:id/contactosAgregar
un
contacto
a
una
personaPOST/personas/subirImagenSubir
una
imagen y ahora…
¿qué hacemos con estos msjs?
Richardson Maturity Model
Documentar…
Uniform Interfaces
• Identificación recursos.
• Manipulación de recursos a través de su
representación.
• Mensajes auto-descriptivos.!
• Hypermedia como motor del estado de la
aplicación (HATEOAS).
auto-descriptivos
¿Cómo procesar el mensaje?
¿qué parser utilizar?
¿Caching?
ahora…
¿cómo son los mensajes?
HAL Collection JSON Siren
HTTP/1.1 200 OK!
Content-Type: application/json!
{!
"status":"ok",!
"message":"Data retrieved OK!",!
"data" : [!
!{!
!! "id": 90, !
!! "modelId": 81, !
!! "path": "Somewhere over the rainbow.rvt"!
!},!
!{!
!! "id": 91, !
!! "modelId": 13, !
!! "path": "Blue birds fly.rvt”!
}]!
}!
GET
http://server/addin/auto-‐harvest/get-‐jobs/ o_O
HTTP/1.1 200 OK!
Content-Type: application/json!
{!
"status":"error",!
"message":"Page not found”,!
"data" : []!
}!
o_O
status codes
2xx - Success
3xx - Redirection
4xx - Client Error
5xx - Server Error
Error messages
api-problem
HTTP/1.1 401 Unauthorized!
Content-Type: application/problem+json!
{!
! "type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",!
! "title": "Unauthorized",!
! "status": 401,!
! "detail": "Unauthorized",!
! "authentication_uri": "/oauth"!
}!
Uniform Interfaces
• Identificación recursos.
• Manipulación de recursos a través de su
representación.
• Mensajes auto-descriptivos.
• Hypermedia como motor del estado de la
aplicación (HATEOAS).
HATEOAS
Clients make state transitions only through
actions that are dynamically identified
within hypermedia by the server. !
Except for simple fixed entry points to the
application, a client does not assume that
any particular action is available for any
described in representations previously
particular resources beyond those
received from the server.
clase.php
public class Customer!
{!
! !public $Id;!
! !public $Name;!
}!
clase.c#
public class Customer!
{!
! public int Id { get; set; }!
! public string Name { get; set; }!
}!
json
{ !
"id" : "1"!
"name" : "Diego"!
}!
HAL
{!
"id": "diego",!
"name": "Diego Sapriza”,!
!
"_links": {!
"self": {!
"href": "http://web.org/api/user/diego"!
},!
"website": {!
"href": "http://web.org/api/locations/diego"!
}!
}!
} !
http://bit.ly/hal-spec
HAL
{!
.. *snip* ..!
"_embedded": {!
"website": {!
"_links": {!
"self": {!
"href": “http://web.org/api/locations/diego"!
}!
},!
"id": "diego",!
"url": "http://diego.uy"!
}!
}!
}!
HAL - colecciones
{!
"_links": {!
"self" :{ "href": "http://web.org/api/user?page=3" },!
"first":{ "href": "http://web.org/api/user" },!
"prev" :{ "href": "http://web.org/api/user?page=2" },!
"next" :{ "href": "http://web.org/api/user?page=4" },!
"last" :{ "href": "http://web.org/api/user?page=133" }!
},!
"count": 3,!
"total": 498,!
...!
}
https://api.github.com
{!
"current_user_url": "https://api.github.com/user",!
"authorizations_url": "https://api.github.com/authorizations",!
"emails_url": "https://api.github.com/user/emails",!
"emojis_url": "https://api.github.com/emojis",!
"events_url": "https://api.github.com/events",!
"feeds_url": "https://api.github.com/feeds",!
"following_url": "https://api.github.com/user/following{/target}",!
"gists_url": "https://api.github.com/gists{/gist_id}",!
"hub_url": "https://api.github.com/hub",!
"issues_url": "https://api.github.com/issues",!
"keys_url": "https://api.github.com/user/keys",!
"notifications_url": "https://api.github.com/notifications",!
"organization_url": "https://api.github.com/orgs/{org}",!
"public_gists_url": "https://api.github.com/gists/public",!
"rate_limit_url": "https://api.github.com/rate_limit",!
"repository_url": "https://api.github.com/repos/{owner}/{repo}",!
"starred_url": "https://api.github.com/user/starred{/owner}{/repo}",!
"starred_gists_url": "https://api.github.com/gists/starred",!
"team_url": "https://api.github.com/teams",!
"user_url": "https://api.github.com/users/{user}",!
"user_organizations_url": "https://api.github.com/user/orgs",!
...!
}!
Richardson Maturity Model
http://bit.ly/api-rmm
Sigamos links
Restful api
versionamiento!
recursos
status codes
autenticación!
mensajes
paginación
documentación!
hypermedia (HATEOAS)
verbos
tools
Versiona tu API
HTTP
GET
https://web.com/api/v1/users/diego
HTTP
GET
https://web.com/api/users/diego
api-‐version:
2
HTTP
GET
https://web.com/api/users/diego
Accept:
application/vnd.myapi.v2+json
HTTP
GET
https://web.com/api/users/diego
por defecto última versión
Headers para versiones anteriores
autenticación
crea tu propio método
HTTP Basic Auth
!
HTTP Digest
!
OAuth2
tools
Postman
Runscope
jsonmate.com
Restful api
versionamiento
recursos
status codes
autenticación
mensajes
paginación
documentación!
hypermedia (HATEOAS)
verbos
tools
@AV4TAr
http://AV4TAr.com
https://speakerdeck.com/av4tar/restful-para-todos
• http://www.troyhunt.com/2014/02/your-api-versioning-is-
wrong-which-is.html
• http://martinfowler.com/articles/
richardsonMaturityModel.html
• http://www.vinaysahni.com/best-practices-for-a-pragmatic-
restful-api
• http://spf13.com/post/soap-vs-rest
• https://leanpub.com/build-apis-you-wont-hate
• https://speakerdeck.com/caseysoftware/on-the-edge-of-
hypermedia-midwest-dot-io
Comentarios de: RESTful 4 all (0)
No hay comentarios