RESTful

Un repaso al tutorial RESTful

Intro

  • Construir RESTful web services (WS) es en parte arte y en parte ciencia.
  • No hay un estándar para construir RESTful WS.
  • Es importante construir RESTful WS de acuerdo a las buenas prácticas de la industria.
  • Las buenas prácticas facilitan el desarrollo e incrementan la adopción por parte del cliente. 

Qué es REST

Las siglas REST significan: REpresentational State Transfer

  • Basado en recursos
  • Representaciones
  • Tiene seis restricciones:
    • Interface uniforme
    • Sin estado (Stateless)
    • Cliente - Servidor
    • Cacheable
    • Sistema en capas
    • Código bajo demanda

Interface Uniforme

 

  • Define la interface entre los clientes y los servidores.
  • Simplifica la arquitectura.
  • Desacopla la arquitectura.
  • Permite la evolución del sistema de manera independiente.

 

Interface Uniforme (cont...)

Interface uniforme tiene cuatro principios guía:

 

  • Basado en recursos.
  • Recursos manipulados a través representaciones.
  • Mensajes autodescriptivos
  • Hypermedia como el motor del estado de la aplicación(HATEOAS)

Stateless

El estado está dentro del request.

  • Como parte de la URI (qué recurso).
  • Como parámetros del query-string.
  • En el body(estado deseado, nuevo, cambiado).
  • En los encabezados(meta-información).

 

No hay sesion client -> server -> cliente

 

Potencia la escalabilidad. Cada petición es una nueva petición.

Stateless (cont...)

 

Manipulación de estado de un recurso:

  1. Server recibe request
  2. Server procesa request a estado apropiado
  3. Comunica el resultado al cliente vía los headers, el Http Status y el response body.

Cacheable

Los clientes pueden cachear respuestas.

Las respuestas deben definir de manera implicita o explicita si son cacheables o no, para reusar o no sus datos en futuras peticiones.

 

Bien manejado, este mecanismo elimina algunas interacciones entre cliente-servidor, mejora escalabilidad e incrementa el performance. 

Cliente - Servidor

  • Clientes y servidores separados.
  • Los clientes no saben del detalle de implementación, almacenamiento y/o tecnología en el servidor y viceversa.
  • La portabilidad aumenta.
  • Código en servidor más simple y más escalable.
  • Clientes y servidores reemplazables, siempre y cuando la interface no se altere.

 

 

Sistema en capas

  • Los clientes no saben si hacen la petición sobre un recurso en un servidor en particular o a un servidor intermedio (API Manager).
  • Los servidores intermedios mejoran la escalabilidad, el balanceo de carga, el monitoreo del flujo de peticiones y permiten agregar politicas de seguridad, entre otras ventajas.  

Código bajo demanda (opcional)

El servidor puede transferir comportamiento (lógica) al cliente para que este último lo ejecute.

 

  • Componentes compilados (Java applets)
  • Client-side scripts (JavaScript)

 

Es la única restricción opcional. Es decir, un servicio web puede denominarse RESTful si cumple todas las restricciones o todas menos esta.

REST API

Consejos rápidos

Usar un verbo HTTP con significado

Los clientes de las APIs usan los verbos HTTP para las operaciones que representan:

  • GET. Leer uno o una colección de recursos.
  • PUT. Actualiza recurso por su identificador.
  • DELETE. Elimina recurso por su identificador.
  • POST. Crea nuevo recurso. Se usa para otras operaciones que no se corresponden con un verbo HTTP, por ejemplo, login, notify, etc.

 

La operación GET no debe cambiar el estado del recurso. Tras un GET el recurso sigue siendo el mismo.

Usar nombre de recurso sensibles

Construir un API es 80% arte y 20% ciencia.

La parte artística es crear una jerarquía URL que represente recursos sensibles.

Ejemplos:

/customer -> todos los clientes
/customer/123 -> cliente 123
/customer/123/orders -> ordenes de cliente 123
/customer/123/orders/45 -> orden 45 de cliente 123
/customer/123/orders/45/products -> productos en orden 45 de cliente 123
/customer/123/ordes/45/products/67 -> producto 67 de orden 45 de cliente 123

Usar nombre de recurso sensibles

Usa identificadores en la URL en lugar de en el query-string:

  • Bien: /customers/123
  • Nada bien: /api?tipo=customer&id=123

Nombra los recursos en su orden natural

Diseña para los clientes, no para tus datos

Nombres de recursos como sustantivos, no como verbos. La acción la define el HTTP Verb

 

Usar nombre de recurso sensibles

Utiliza plurales en los nombres de recursos

Si se trata de colecciones:

  • Bien /customers
  • Nada bien /customer_list

Utiliza lower-case en segmentos, separando palabras con "-" 

  • Bien /api/global-shop/monthly-promotions
  • Nada bien /API/GlobalShop/monthlyPromotion

URIs cortas, tanto como sea posible, no restando significado

 

Usar HTTP Response Codes para indicar Status

Son un estándar.

Existe uno para casi todas las situaciones.

Usar los relevantes en cada situación.

Ejemplo:

Create resource -> 201 CREATED

 

Usar JSON en lugar de XML

JSON

{
    "montoCredito": 200000.00,
    "comisionAnual": 1100,
    "tasaInteresAnual": 35,
    "pagoMinimo": 10
}

 

XML

<?xml version="1.0" encoding="UTF-8" ?>
<montoCredito>200000</montoCredito>
<comisionAnual>1100</comisionAnual>
<tasaInteresAnual>35</tasaInteresAnual>
<pagoMinimo>10</pagoMinimo>

Métodos HTTP en RESTful WS

Cada quien con su cada cual'

Acciones sobre los recursos

Los más usados:

  • POST
  • GET
  • PUT
  • DELETE

Se corresponden con las operaciones CRUD sobre los recursos.

Otros verbos no tan utilizados con REST

  • PATCH
  • HEAD
  • OPTIONS

Correspondencia verbo HTTP, operación CRUD, Response code

Verbo HTTP Operación CRUD Response Code
POST Create 201 Created, 404, 409
GET Read 200 OK, 404
PUT Update/Replace 200, 204, 404
DELETE Delete 200, 404

POST

  • Para crear nuevos recursos.
  • En particular, para crear recursos subordinados (a un parent resource)
  • Regresa un 201 en caso de éxito.
  • No es seguro ni idempotente, es decir, dos request POST idénticas resultará en dos recursos con la misma información. La validación debe ser a mano.

 

Ejemplos POST:

  • POST https://api.invexbt.com/customers
  • POST https://api.invexbt.com/customers/12345/cards

GET

  • Para leer (recuperar) la representación de un recurso.
  • Si no se produce ningún error, regresa JSON (XML) y un response code 200 OK. 404 si no existe el recurso.
  • Lee datos, no modifica datos.
  • Idempotente, esto es, multiples llamadas GET devuelven el mismo resultado que una sola.
  • No debe usarse para acciones que modifican el estado de los recursos.

Ejemplos:

  • GET https://api.invexbt.com/customers/12345
  • GET https://api.invexbt.com/customers/12345/offers

UPDATE

  • Para actualizaciones/modificaciones.
  • Recibe identificador del recurso y la representación del nuevo estado del recurso.
  • Regresa un 200 OK, 404 not found, 400 Bad Request.
  • No se recomienda regresar el recurso en respuesta.
  • No es seguro, pero es idempotente, es decir, cambia el estado del recurso, pero las invocaciones posteriores a la primera producen el mismo estado final del recurso. No es idempotente si por ejemplo la actualización mueve un incrementador en cada llamada.

Ejemplos:

  • PUT https://api.invexbt.com/customers/12345
  • PUT http://api.invexbt.com/customers/12345/orders/98765

DELETE

  • Se entiende su uso
  • La URI contiene el identificador del recurso.
  • Regresa 200 OK, 204, 404.
  • Es idempotente, es decir, elimina el recurso y las invocaciones posteriores no afectan porque el recurso ya no está. Aunque la respuesta no será 200 sino 404

Ejemplos:

  • DELETE http://api.invexbt.com/customers/12345/order/67
  • DELETE http://www.example.com/customers/12345

Resource Naming

Diseña para los clientes, no para los datos

Nombres de recursos con significado

Es de los temas más debatidos a la hora de diseñar APIs

  • Recursos bien nombrados = API intuitiva, fácil de usar
  • Recursos mal nombrados = Klutsy API, difícil de usar y entender

Una RESTful API es una combinación de una colección de URIs (recursos) y operaciones sobre esas URIs (verbos HTTP), más el uso de buenas prácticas y convenciones.

Ejemplos de recursos:

  • Usuarios de un sistema
  • Cursos en los que un estudiante está enrolado
  • Un artículo de un blog.

URIs y recursos

Cada recurso en el API tiene al menos una URI que lo identifica.

Es mejor si la URI tiene sentido y describe al recurso.

 

Se presentan ejemplos de nombrado correcto de recursos para un API que expone clientes, ordenes de compra, linea de productos y productos.

Buenos nombres de URIs

Para insertar (crear) un nuevo cliente en el sistema, deberíamos usar:

  • POST https://api.invexbt.com/customers

Para consultar un cliente el ID# 33245:

  • GET https://api.invexbt.com/customers/33245

La misma URI debería ser usada para PUT y DELETE.

Aqui una URI propuesta para crear un producto:

  • POST https://api.invexbt.com/products 
  • GET|PUT|DELETE https://api.invexbt.com/products/66432

Buenos nombres de URIs (cont...)

Cómo relacionar un recurso OrdenDeCompra y cliente?

Primer intento:

  • POST http://www.example.com/orders

Crea la orden? Sí, pero el problema es que esto no relaciona la orden con un cliente. La orden está fuera del contexto del cliente. Veamos un segundo intento:

  • POST http://www.example.com/customers/33245/orders

Claramente se entiende que estamos creando una orden de compra para el cliente con ID#33245

Una jerarquía más profunda sería:

  • POST http://www.example.com/customers/33245/orders/8769/lineitems
  • GET http://www.example.com/customers/33245/orders/8769/lineitems/1

Nombres de URIs Anti-patterns

Así no se deben nombrar recursos.

Usar query-parameter para indicar la operacion y el verbo HTTP.

GET http://api.example.com/services?op=update_customer&id=12345&format=json

"Services" es sustantivo, pero no autodescriptivo.

Usa GET para un UPDATE.  :O

Problemático (incluso peligroso) para el cliente.

Igual de peligroso es:

  • GET http://api.example.com/update_customer/12345

  • GET http://api.example.com/customers/12345/update

  • PUT http://api.example.com/customers/12345/update

     

Referencias

  • http://www.restapitutorial.com/ 
  • http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
  • https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
  •  

Gracias

RESTful Resource Naming

By Augusto Alonso de la Cruz Jimenez

RESTful Resource Naming

  • 35