Your SlideShare is downloading. ×
0
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
Introducción a REST - SymfonyVLC
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

Introducción a REST - SymfonyVLC

1,494

Published on

Transparencias de la charla sobre introducción a REST en SymfonyVLC el 8/10/2013

Transparencias de la charla sobre introducción a REST en SymfonyVLC el 8/10/2013

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,494
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
45
Comments
0
Likes
3
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. Servicios Web REST Breve introducción a REST
  • 2. Contenido de la charla • Qué es REST? o o o o o Definición Conceptos Verbos HTTP Códigos de respuesta Ejemplos • APIs CRUD o Operaciones sobre recursos o Problemas de concurrencia o Operaciones asíncronas • Seguridad en REST • Testing y pruebas
  • 3. Sobre mi • Programador web PHP desde hace 4 años (aprox. 1 con Symfony2). • Muy fan de NodeJS, Angular y Javascript en general • Aficionado a la seguridad informática y redes.
  • 4. Qué es REST? Definición y conceptos
  • 5. Qué es REST?  Es una tecnología?
  • 6. Qué es REST?  Es una tecnología? ✗  Es una arquitectura?
  • 7. Qué es REST?  Es una tecnología? ✗  Es una arquitectura? ✗  Es un “estilo arquitectónico”?
  • 8. Qué es REST?  Es una tecnología? ✗  Es una arquitectura? ✗  Es un “estilo arquitectónico”? ✓ Cuando hablamos de REST nos referimos a una forma de implementar una arquitectura en concreto (arquitectura WebService) por eso solemos decir que REST es sólo un estilo de elaborar servicios web.
  • 9. Qué significa REST? REpresentational State Transfer
  • 10. ¿Qué es REST? • La primera vez que se habló de REST fue en el año 2000 en la tesis doctoral de Roy Fielding, uno de los principales autores del protocolo HTTP • Está orientado a transferencias de recursos, no a llamadas de procedimientos remotos (RPC) • Hace un uso muy eficiente del protocolo HTTP, rompe con el esquema de la web que funciona solo con GET y POST
  • 11. REST en la actualidad • A día de hoy se conoce por REST a casi cualquier servicio Web que trabaje con XML y HTTP • La mayor parte de las APIs existentes son simples interfaces para interactuar con la base de datos (CRUD básico) • REST nos permite modelar totalmente nuestro negocio sin importar el lenguaje en que este implementado el servicio o el cliente
  • 12. Conceptos y reglas • El servicio representará recursos, no acciones o No se publican verbos como “comprar” o Se usan recursos como “pedido” o “compra” • Todos los recursos deben de poseer un UUID o Universal Unique Identifier o Todo recurso en REST necesita un UUID para ser identificado dentro del sistema • La forma en que se represente internamente un recurso debe ser privada • Todos los recursos deben de poseer un interfaz de operaciones, y todos deben de implementarlas.
  • 13. Cómo funciona? • Las operaciones se realizan por transferencia de estado o El cliente pide una copia del recurso al servicio o El cliente modifica el recurso o El cliente transfiere el recurso actualizado al servicio • Los recursos deben ser multimedia o Los recursos deben de poder expresarse en más de un formato • JSON, XML, CSV… o En las peticiones podemos y debemos indicar el tipo de formato que admitimos, o una lista con varios, ordenada por prioridades. • Según la implementación que se consiga, un API se cataloga en uno de los niveles REST
  • 14. Verbos HTTP • El protocolo HTTP define un conjunto de verbos que nos permiten realizar todo tipo de operaciones: o o o o o o GET (LEER) PUT (CREAR O ACTUALIZAR RECURSO COMPLETO) POST (CREAR, ACTUALIZAR PARCIALMENTE UN RECURSO) PATCH (ACTUALIZAR PARCIALMENTE UN RECURSO) DELETE (BORRAR) OPTIONS (CONSULTAR OPERACIONES) • http://www.restapitutorial.com/lessons/httpmethods.html • Usarlos incorrectamente lleva a desastres como el de Basecamp. o http://www.mail-archive.com/isn@attrition.org/msg04213.html
  • 15. POST e idempotencia • POST es él verbo “maldito” por REST, al no ser idempotente. • La idempotencia asegura que ejecutar n veces una transferencia obtendrá el mismo resultado. • Se usa para modelar operaciones como: o Crear recursos o Modificar parcialmente recursos…
  • 16. Códigos de Respuesta • El resultado de una transferencia REST viene dado por el código de estado de la respuesta HTTP, en REST, los más habituales son: o o o o o o o o o o o o • 200 (OK) 201 (Creado) 202 (Aceptado) 204 (Sin contenido) 304 (No modificado) 400 (Petición mal formada) 401 (No autorizado) 403 (Acceso no permitido) 404 (No encontrado) 409 (Conflicto) 412 (Fallo de pre-condición) 500 (Problema de Servidor) http://www.restapitutorial.com/httpstatuscodes.html
  • 17. VEAMOS EJEMPLOS!
  • 18. Ejemplos En nuestra API de pruebas usaremos: • GET o o • Eliminar recursos o • Actualizaciones totales de recursos o • Actualizaciones parciales o • Creación de recursos o • Obtener recursos o colecciones de recursos Consultar acciones disponibles POST PATCH PUT DELETE OPTIONS La URL sobre la que trabajaremos será: http://symfonyvalencia.es/api/usuarios El servidor puede devolver datos en XML o en JSON
  • 19. Transferencia OPTIONS Consultar acciones Cliente OPTIONS /api/usuarios/B2K1E3 Host: www.symfonyvalencia.es Servidor HTTP/1.1 200 OK Allow: GET, PUT, POST, OPTIONS, DELETE, PATC H
  • 20. Transferencia GET Obtener una Colección Cliente GET /api/usuarios HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Servidor
  • 21. Transferencia GET Obtener una Colección Cliente GET /api/usuarios HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Servidor HTTP/1.1 200 OK Content-Type: application/json [{ “id”: “X1B4Z3”, “nombre”: “Miguel Ángel”, “edad”: 27, “lenguajes”: [“PHP”, “Javascript”] }, { “id”: “AB325J”, “nombre”: “Ángel Miguel”, “edad”: 26, “lenguajes”: [“Ruby”, “Java”] }]
  • 22. Transferencia GET Obtener un registro Cliente GET /api/usuarios/X1B4Z3 HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Servidor
  • 23. Transferencia GET Obtener un registro Cliente GET /api/usuarios/X1B4Z3 HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Servidor HTTP/1.1 200 OK Content-Type: application/json Etag: W/2cc7-3f3ba34cc25d { “id”: “X1B4Z3”, “nombre”: “Miguel Ángel”, “edad”: 27, “lenguajes”: [“PHP”, “Javascript”] }
  • 24. Transferencia POST Crear un recurso Cliente POST /api/usuarios HTTP/1.1 Host: www.symfonyvalencia.es Content-Type: application/x-wwwform-urlencoded Accept: application/json nombre=Manolo&edad=26&localidad =Valencia Servidor
  • 25. Transferencia POST Crear un recurso Cliente POST /api/usuarios HTTP/1.1 Host: www.symfonyvalencia.es Content-Type: application/x-wwwform-urlencoded Accept: application/json nombre=Manolo&edad=26&localidad =Valencia Servidor HTTP/1.1 201 Created Content-Type: application/json Location: http://symfonyvalencia.es/usuarios/B2 K1E3 Etag: W/2cc7-3f3ba34cc25d { ”id”: “B2K1E3” }
  • 26. Transferencia PUT Actualizar un recurso Cliente PUT /api/usuarios/X1B4Z3 Host: www.symfonyvalencia.es Content-Type: application/json Accept: application/json { “nombre”: “Miguel Ángel”, “edad”: 27, “lenguajes”: [„PHP‟, „Javascript‟], “localidad”: “Valencia” } Servidor
  • 27. Transferencia PUT Actualizar un recurso Cliente PUT /api/usuarios/X1B4Z3 Host: www.symfonyvalencia.es Content-Type: application/json Accept: application/json { “nombre”: “Miguel Ángel”, “edad”: 27, “lenguajes”: [„PHP‟, „Javascript‟], “localidad”: “Valencia” } Servidor HTTP/1.1 204 No Content Content-Type: application/json Etag: W/2cc7-3f3ba34cc25d
  • 28. Transferencia DELETE Eliminar un recurso Cliente DELETE /api/usuarios/B2K1E3 Host: www.symfonyvalencia.es Servidor HTTP/1.1 204 No Content
  • 29. API’S CRUD Las API‟s CRUD son el tipo de API más extendido en el mundo REST
  • 30. APIs CRUD • Son las APIs más habituales • CRUD o o o o Create (crear) Read (leer) Update (actualizar) Delete (borrar) • Cubren las operaciones básicas que realizamos habitualmente sobre entidades • Implementan todos los verbos HTTP • Son lo contrario a APIs read-only • Son bastante sencillas de implementar • En Symfony2 existen bundles que facilitan su implementación, como FOSRESTBundle
  • 31. APIs CRUD • Si pretendemos ceñirnos absolutamente al concepto de API REST, no debemos de diseñar nuestra API como un reflejo de las entidades, ya que expone nuestro esquema de base de datos. • Un cambio en una entidad no debería de afectar al uso del API. • Se trata de modelar nuestro negocio con operaciones sobre recursos no de crear un interfaz para gestionar nuestra base de datos.
  • 32. Acceso concurrente • Si a nuestro Web Service se conectan simultáneamente varias personas y modifican el mismo registro… ¿Puede haber problemas de inconsistencia? • El problema de la inconsistencia en REST se soluciona habitualmente con la inclusión de cabeceras Etag y If-Match. • Se utilizan Etags débiles, ya que las fuertes son demasiado estrictas para nuestro propósito
  • 33. Ejemplo 1/3 Cliente GET /api/usuarios/X1B4Z3 HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Servidor HTTP/1.1 200 OK Content-Type: application/json;charset=utf-8 Etag: W/689438a788bbc2e { “id”: “X1B4Z3”, “nombre”: “Miguel Ángel”, “edad”: 27, “lenguajes”: [“PHP”, “Javascript”] }
  • 34. Ejemplo 2/3 Cliente PUT /api/usuarios/X1B4Z3 HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json If-Match: W/689438a788bbc2e Content-Type: application/json { “id”: “X1B4Z3”, “nombre”: “Miguel Ángel Sánchez”, “edad”: 23, “lenguajes”: [“PHP”, “Javascript”], “localidad”: “Valencia” } Servidor (Match OK) HTTP/1.1 204 No Content Etag: W/91246ef669ab7
  • 35. Ejemplo 3/3 Cliente PUT /api/usuarios/X1B4Z3 HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json If-Match: W/689438a788bbc2e Content-Type: application/json { “id”: “X1B4Z3”, “nombre”: “Miguel Ángel Sánchez”, “edad”: 23, “lenguajes”: [“PHP”, “Javascript”], “localidad”: “Valencia” } Servidor (Match KO) HTTP/1.1 412 Precondition Failed Etag: W/91246ef669ab7
  • 36. Actualizaciones parciales • Otro problema básico en REST es la actualización parcial del contenido. • Si usamos PUT, sobrescribimos todo el recurso, ¿y si solo queremos cambiar un atributo del recurso? • El método habitual se basa en crear nuevos tipos MIME de cambio de estado o diff y usar POST. • La solución moderna pasa por usar el verbo PATCH, funciona igual que con POST, pero es más semántico y solo admite tipos MIME que representen diffs
  • 37. Actualizaciones parciales • Cuando hablamos de diffs hablamos de crear un formato o tipo MIME que represente una operación de actualización parcial sobre un registro. • Suelen nombrarse como: o application/recurso-diff+formato • Recurso es el tipo de entidad (usuario, factura…) • Formato puede ser cualquier formato (json, xml…) • Ejemplos: o application/usuario-diff+json o application/usuario-diff+xml
  • 38. Ejemplo de actualización PATCH /api/usuarios/X1B4Z3 HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json If-Match: W/979c576c5be5fa5 Content-Type: application/usuario-diff+json [{ }, { }] “tipo-cambio”: “sustituir”, “campo”: “edad”, “valor”: “23” “tipo-cambio”: “anadir”, “campo”: “localidad”, “valor”: “Valencia”
  • 39. Operaciones de larga duración o asíncronas
  • 40. Operaciones de larga duración o asíncronas Cuando las operaciones no son inmediatas, o deben ser encoladas porque se procesan en bloque a cierta hora mediante un cron, o necesitan validación de un servicio externo (pasarelas de pago, Paypal…), el usuario debe de poder seguir el estado del recurso. Con REST es posible modelar operaciones asíncronas o encolables creando un recurso intermedio que represente el estado del recurso antes de finalizar su creación.
  • 41. Ejemplo • Vamos a realizar un pago a una tienda online vía REST • El pago debe de ser validado por la entidad bancaria que implementa la pasarela de pago. • El proceso puede tardar entre 3 y 5min • El cliente desea saber cuando ha sido validado el pago
  • 42. Ejemplo 1/4 Cliente POST /api/pago HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Content-Type: application/json Servidor HTTP/1.1 202 Accepted Location: /api/cola-pago/XBC3719 { “location”: “/api/cola-pago/XBC3719”, “estado”: “pendiente” { “metodo”: “visa”, “numtarjeta”: 1234567812345678, “cvv”: 123 “caducidad”: “12/17” “cantidad”: 2500 } }
  • 43. Ejemplo 2/4 Cliente GET /api/cola-pago/XBC3719 HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Servidor HTTP/1.1 200 OK Content-Type: application/json { “estado”: “pendiente” }
  • 44. Ejemplo 3/4 Cliente GET /api/cola-pago/XBC3719 HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Servidor (Pago OK) HTTP/1.1 200 OK Content-Type: application/json { “estado”: “ok”, “id”: “/api/pago/DEB743AC” }
  • 45. Ejemplo 3 bis/4 Cliente GET /api/pago/DEB743AC HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Servidor (Pago OK) HTTP/1.1 200 OK Content-Type: application/json { “metodo”: “visa”, “numtarjeta”: 1234567812345678, “cvv”: 123 “caducidad”: “12/17” “cantidad”: 2500 “estado”: “pagado” }
  • 46. Ejemplo 4/4 Cliente GET /api/cola-pago/XBC3719 HTTP/1.1 Host: www.symfonyvalencia.es Accept: application/json Servidor (Error de pago) HTTP/1.1 200 OK Content-Type: application/json { “estado”: “error”, “error”: “sin fondos }
  • 47. Seguridad en REST No todas las API‟s son públicas
  • 48. Seguridad en REST • En el contexto de un servicio REST no existe el concepto de Sesión, ya que HTTP es un protocolo Stateless no orientado a conexión. • Si nuestra API necesita autenticar a sus usuarios, estos deben de hacerlo en cada petición • Esto simplifica un ataque por parte de intrusos • Veamos algunas normas básicas de seguridad en REST
  • 49. 1. No uses IDs predecibles
  • 50. 1. No uses IDs predecibles • Cualquier intruso que sniffe nuestro tráfico y detecte una petición del tipo: GET /api/usuario/1/datos-bancarios • Se verá tentado de probar con: GET /api/usuario/2/datos-bancarios GET /api/usuario/3/datos-bancarios GET /api/usuario/n/datos-bancarios • Tampoco debemos usar las claves primarias de nuestra base de datos, nos exponemos a ataques SQLi
  • 51. 2. Usa HTTPS
  • 52. 2. Usa HTTPS • Con el protocolo HTTPS ya tenemos ganado la mitad • Es un protocolo seguro y el contenido va cifrado, tanto para peticiones como para respuestas. • Si transmitimos información sensible no será fácilmente reproducible por un atacante que haya usado un sniffer • Nos da seguridad a la hora de transmitir contraseñas
  • 53. 3. Genera Tokens de seguridad
  • 54. 3. Genera Tokens de seguridad • Si creamos nuestro propio esquema de seguridad, generando Tokens que caduquen cada cierto tiempo, evitaremos transmitir la contraseña demasiadas veces. • Después de la primera autenticación, el servidor nos transmite nuestro Token • En las próximas peticiones lo incorporaremos en una cabecera, o una cookie
  • 55. 4. Usa criptografía hardcore
  • 56. 4. Algoritmo HMAC • Nos puede ayudar a construir buenos Tokens PARTE_PUBLICA = UUID + “:” + NIVEL_SEGURIDAD + ”:” + TIMESTAMP FIRMA = HMAC(CLAVE_SECRETA, PARTE_PUBLICA) TOKEN = FIRMA + ”_” + PARTE_PUBLICA • Desde el servidor basta con descomponer el Token en las componentes FIRMA y PARTE_PUBLICA, volver a calcular la firma con la PARTE_PUBLICA recibida y comparar la firma generada con la recibida
  • 57. 4. Algoritmos ajustables • Algoritmos como BCRYPT o PBKDF aceptan un parámetro de “complejidad”, que permiten indicar cuanto tardará en calcularse la contraseña. • Esto limita los ataques de fuerza bruta, por ejemplo, con una complejidad de 500ms solo podrían probarse 2 passwords por segundo.
  • 58. 5. Usa OAuth
  • 59. 5. Usa OAuth • Una opción alternativa a generar nuestros tokens es implementar un servidor OAuth que nos permita acceder a nuestra API • Existen librerías en casi todos los lenguajes que implementan OAuth • Podemos incluso usar nuestros credenciales en redes sociales para acceder a nuestra API.
  • 60. Testing y pruebas Asegurándonos de que todo anda bien
  • 61. Testing y pruebas
  • 62. Testing y pruebas • Como cualquier otro programa, aplicación web… que desarrollemos, las APIs REST se pueden implementar usando TDD. • Es importante testear siempre que todos los códigos de respuesta devueltos son adecuados, tanto para casos de éxito como para casos de error. • IMPORTANTE: Muchos frameworks implementan listeners de excepciones y evitan, por ejemplo que una página devuelva un 404, enmascarando el resultado con una respuesta 200.
  • 63. Testing con xUnit • Podemos usar tranquilamente nuestro framework de pruebas xUnit para testear, no solo los códigos de respuesta, sino toda la lógica de negocio. • Las prácticas habituales de testing con este tipo de herramientas son totalmente válidas para el testeo.
  • 64. Testing con cURL
  • 65. Testing con cURL • Es una alternativa para realizar nuestros tests (cURL + Shell Script) • Con cURL podemos crear exactamente la transferencia que buscamos. • Si se tienen suficientes conocimientos sobre cURL se pueden crear buenos tests con un tiempo de ejecución bastante bajo.
  • 66. Testing con Guzzle … porque cURL no es para todos los públicos
  • 67. Testing con Guzzle (PHP) • Guzzle es una librería en PHP que actúa como un wrapper de cURL, exprimiendo al máximo su potencia. • Permite crear clientes REST muy potentes y escalables • Es realmente sencillo de utilizar y es orientado a objetos • Se integra bien con PHPUnit.
  • 68. Testing con POSTMAN
  • 69. Testing con POSTMAN • POSTMAN es un plugin para Chrome que actúa como cliente REST • Nos permite guardar las transferencias preconfiguradas • Permite autenticación mediante OAuth de forma bastante sencilla • No es una herramienta automática (hay que ejecutar manualmente cada test y comprobar su resultado), por lo que no es recomendable testear sólo con POSTMAN
  • 70. Documentación con Swagger
  • 71. Documentación con Swagger • Swagger es un estándar para definición de APIs REST y un framework que nos permite visualizar su representación y también consumir el API. • Es una herramienta muy útil para publicar nuestra API y que todo el mundo aprenda a usarla rápidamente. • Existe un bundle para Symfony2 que implementa Swagger: NelmioApiDocBundle

×