REST - deSymfony2012

52

description

Repasaremos conceptos y principios para que una arquitectura sea RESTfull, se explicará cómo se ha plateado el framework Leophard para seguir estos y otros principios.

Transcript of REST - deSymfony2012

Page 1: REST - deSymfony2012
Page 2: REST - deSymfony2012
Page 3: REST - deSymfony2012

Hola

Asier Marqués

Simettric, Fundador.

4VisionsManager.com, Socio y director técnico.

Page 4: REST - deSymfony2012

Desacoplar el cliente del backend

• Mayor escalabilidad

• Separación de problemas

• División de especialidades

• API uniforme para todos los clientes

Page 5: REST - deSymfony2012

REST

Page 6: REST - deSymfony2012

REST

REpresentational State Transfer

Un estilo de arquitectura para

desarrollar aplicaciones web distribuidas

que se basa en el uso del protocolo

HTTP e Hypermedia.

Definido en el 2000 por Roy Fielding

Page 7: REST - deSymfony2012

Una buena API REST

No tiene estado en el backend.

Está desacoplado del cliente.

Dispone de una interfaz uniforme

(basada en URIs)

Page 8: REST - deSymfony2012

Richardson Maturity Model

# Nivel 1 (Pobre):

Se usan URIs para identificar recursos

# Nivel 2 (Medio):

Se usa el protocolo HTTP adecuadamente

# Nivel 3 (Óptimo):

Se implementa hypermedia.

http://www.crummy.com/writing/speaking/2008-QCon/act3.html

Page 9: REST - deSymfony2012

Recursos, URIs, hypermedia?

Page 10: REST - deSymfony2012

REST: Nivel 1

URIs

Page 11: REST - deSymfony2012

URI, uniform resource identifier

Identifica un recurso

Pueden identificar un

recurso por nombre

(URN) o por

localización (URL)

Page 12: REST - deSymfony2012

Recurso?

Page 13: REST - deSymfony2012

Recursos

/users Listado de usuarios

/users/{id} Un usuario

Page 14: REST - deSymfony2012

Reglas para identificar recursos

• Se debe *identificar* un recurso!

• Las URIs se construyen con nombres

nunca con verbos

• Deberían tener una estructura

jerárquica

Page 15: REST - deSymfony2012

URIs incorrectas

Nunca se usan verbos

/getUser/{id}

/users/{id}/edit

/login

Deben ser jerárquicas

/invoices/user/{id}

Identifican un recurso

/invoices/page/2

Page 16: REST - deSymfony2012

URIs válidas

Nunca se usan verbos

/users/{id}

/users/{id}

/access-token

Deben ser jerárquicas

/user/{id}/invoices

Identifican un recurso

/invoices/?page=2

Page 17: REST - deSymfony2012

Formatos

No se debería indicar el formato en la

URI, el formato no identifica al recurso

/invoices.html

/invoices.css

/invoices.xml

Page 18: REST - deSymfony2012

Para eso está HTTP

Request:

GET accept: text/html /invoices

Response:

200 content-type: text/html

Response:

406 Not Acceptable

Page 19: REST - deSymfony2012

REST: Nivel 2

HTTP como framework

Page 20: REST - deSymfony2012

HTTP como Framework

• Protocolo de transporte

• Métodos

• Códigos de estado

• Content-Type

• Gestión de versiones

• Cache

Page 21: REST - deSymfony2012

HTTP: Métodos

GET Recupera el recurso

POST Crea un nuevo recurso

PUT Edita el recurso

POST/PATCH Edita el recurso parcialmente

DELETE Elimina el recurso

Page 22: REST - deSymfony2012

Métodos

Request: GET /users

Response: 200 content-type:application/json

Request: POST /users

Response: 201 content-type:application/json

Page 23: REST - deSymfony2012

Métodos

Request: GET /users/11

Response: 200 content-type:application/json

Request: PUT /users/11

Response: 200 content-type:application/json

Request: DELETE /users/11

Response: 204 no content

Page 24: REST - deSymfony2012

HTTP: Códigos de estado

Page 25: REST - deSymfony2012
Page 26: REST - deSymfony2012

HTTP: Content-Type y Accept

Page 27: REST - deSymfony2012

Content-Type y Accept

• Content-Type nos dice qué tipo de

representación tiene el recurso al que

estamos accediendo.

• Con Accept le decimos qué tipo de

representación queremos.

Page 28: REST - deSymfony2012

HTTP: ETag

Page 29: REST - deSymfony2012

HTTP: Etag y Last-Modified

• Con Etag podemos controlar si el recurso se

ha modificado desde la última vez que

accedimos con un hash.

• If-None-Match se encarga de indicar que la

petición sea efectiva siempre y cuando el

eTag sea distinto, If-Match hace lo inverso.

• Last-Modified/If-Modified-Since permiten

saber si un recurso se ha modificado en base

a una fecha.

Page 30: REST - deSymfony2012

REST: Nivel 3

Hypermedia

Page 31: REST - deSymfony2012

Hypermedia?

Page 32: REST - deSymfony2012

Hypermedia

• Se basa en la idea de enlazar

recursos.

• Para que sea útil, el cliente debe

saber que en la respuesta hay

contenido hypermedia.

• En content-type es clave para esto

Page 33: REST - deSymfony2012

<bill rel=“http://api.servicio.com/doc/order”>

<id>666</id>

<currency>EUR</currency>

<items>..</items>

<amount>67</amount>

<status>UNPAID</status>

<links>

<link rel=“payment”>

http://api.servicio.com/order/666/payment

</link>

<link rel=“cancel”>

http://api.servicio.com/order/666/cancelation

</link>

</links>

</bill>

Page 34: REST - deSymfony2012

Hypermedia

¿Content-Type: text/xml?

Page 35: REST - deSymfony2012

Hypermedia

Content-Type: text/xml

Content-Type:

application/servicio+xml

Page 36: REST - deSymfony2012

RFC4627 JSON Hypertext Application Language

Content-Type: application/hal+json

{

"_links": {

"self": {"href": "/orders/523" },

"warehouse": {"href": "/warehouse/56" },

" invoice": {"href": "/invoices/873“}

},

"currency": "USD",

"status": "shipped",

"total": 10.20

}

http://tools.ietf.org/html/draft-kelly-json-hal-00

Page 37: REST - deSymfony2012

Herramientas

Curl

RestClient

Swagger UI (swagger.wordnik.com)

Page 38: REST - deSymfony2012

Servicios

3scale.com

apigee.com

Page 39: REST - deSymfony2012

Crear un Framework REST

Page 40: REST - deSymfony2012

Puntos clave de un framework

• Facilitarnos el trabajo

• Definir una forma de trabajo común

• Reducir tareas repetitivas

Page 41: REST - deSymfony2012

Symfony2 Components

HTTP Foundation

Routing

ClassLoader

Console

Page 42: REST - deSymfony2012

HTTP Foundation

• Se basa en dos objetos: Request y

Response

• Nos aisla de variables de entorno,

servidor, headers…

Page 43: REST - deSymfony2012

Routing

• Podemos definir URIs mediante

patrones

• Requisitos en las URIs de métodos

HTTP y parámetros.

• Varios tipos de Matcher para

identificar la URI actual.

Page 44: REST - deSymfony2012

Console

• Nos permite crear comandos para

shell

• Cada comando es una clase, permite

definir parámetros, atributos para el

comando

• Los menús se generan de forma

automática

Page 45: REST - deSymfony2012

Crear un framework REST

• Crearlo sobre una aplicación real

• Utilizar el componente Console para

automatizar tareas repetitivas

• Pensar en la organización del código

Page 46: REST - deSymfony2012

Crear un framework REST

• Eventos

• Permitir extensibilidad

• Configuraciones, diferentes entornos

• Logs y gestión de excepciones

Page 47: REST - deSymfony2012

Crear un framework REST

• Sólo lo estrictamente necesario en el

core

• Documentación

• Cobertura de tests

• Aprende de otros

Page 48: REST - deSymfony2012

C

O

N

V

E

N

C

I

Ó

N

Page 49: REST - deSymfony2012
Page 50: REST - deSymfony2012
Page 51: REST - deSymfony2012

Documentación

Page 52: REST - deSymfony2012

Gracias :)

@asiermarques