o Conceptos o Verbos HTTP o Códigos de respuesta o Ejemplos • APIs CRUD o Operaciones sobre recursos o Problemas de concurrencia o Operaciones asíncronas • Seguridad en REST • Testing y pruebas
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.
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
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
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.
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
verbos que nos permiten realizar todo tipo de operaciones: o GET (LEER) o PUT (CREAR O ACTUALIZAR RECURSO COMPLETO) o POST (CREAR, ACTUALIZAR PARCIALMENTE UN RECURSO) o PATCH (ACTUALIZAR PARCIALMENTE UN RECURSO) o DELETE (BORRAR) o 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/[email protected]/msg04213.html
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…
viene dado por el código de estado de la respuesta HTTP, en REST, los más habituales son: o 200 (OK) o 201 (Creado) o 202 (Aceptado) o 204 (Sin contenido) o 304 (No modificado) o 400 (Petición mal formada) o 401 (No autorizado) o 403 (Acceso no permitido) o 404 (No encontrado) o 409 (Conflicto) o 412 (Fallo de pre-condición) o 500 (Problema de Servidor) • http://www.restapitutorial.com/httpstatuscodes.html
Obtener recursos o colecciones de recursos • POST o Creación de recursos • PATCH o Actualizaciones parciales • PUT o Actualizaciones totales de recursos • DELETE o Eliminar recursos • OPTIONS o Consultar acciones disponibles La URL sobre la que trabajaremos será: http://symfonyvalencia.es/api/usuarios El servidor puede devolver datos en XML o en JSON
o Create (crear) o Read (leer) o Update (actualizar) o 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
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.
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
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
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
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.
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
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
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
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
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
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
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.
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.
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.
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.
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.
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.
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
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