domingo, 26 de febrero de 2017

¿Qué es REST? - Introducción y buenas prácticas

Hello again!!!, es hora de familiarizarnos un poco con REST (REpresentational State Transfer) y de tomar algunas buenas prácticas para su utilización. Antes de comenzar les recordaré que esto no es una caceria de brujas :D, no importa la manera en que se implemente mientras se mantenga la consistencia a lo largo de la API (aunque lo mejor es mantener una coherencia con las apis ya existentes para que sea mucho más simple consumir la API para un desarrollador, sean amables con ustedes mismos XD  , un excelente ejemplo es la api de github que es genial >_< )

Ahora a lo nuestro, llevo meses pensando en escribir este post y nunca parece haber el tiempo así que a darle átomos:

En general REST describe como se puede comunicar un sistema con otro (es un estilo de arquitectura para diseñar aplicaciones que se comunicarán unas con otras a través de la red).

En REST utilizamos el protocolo Http para obtener un recurso o realizar transformaciones en el mismo. Por ejemplo, si quiero obtener los datos de un Usuario, utilizaría una petición GET al siguiente URL:

http://api.rest.com/usuarios     - (GET para obtener datos)

Pero no solamente necesitamos obtener recursos, también necesitamos transformarlos, y para ello utilizamos otros verbos. Por ejemplo, para crear el recurso Usuario (solo recordar que el crear no siempre implica una base de datos), se utiliza el verbo POST y se envía la información del recurso en el cuerpo (body) del mensaje:

http://api.rest.com/usuarios - (POST para guardar un dato)
body:
{
  "usuario": "juan",
  "nombre": "Juan Perez",
  "permisos": ["lectura", "escritura"]
}

En el caso de eliminar un recurso de tipo Usuario, utilizamos el verbo DELETE agregándole además, un identificador del recurso que se quiere eliminar. Para el ejemplo, eliminaremos el recurso que guardamos con POST anteriormente:

http://api.rest.com/usuarios/juan - (DELETE para guardar un dato)

También necesitamos actualizar o modificar recursos, para esto, utilizamos los verbos PUT o PATCH y enviamos los datos para modificar en el cuerpo del mensaje. Por ejemplo, si se quiere modificar el recurso que agregamos anteriormente y cambiarle el nombre:

http://api.rest.com/usuarios/juan - (PATCH para guardar un dato)
body:
{
  "nombre": "Juan Perez Ochoa"
}

En general:

VERBO USO CARACTERÍSTICAS
GET Para obtener los datos de un recurso Idempotente*
POST Para crear un nuevo recurso
PUT Para actualizar un recurso completo, también puede utilizarse para crear un nuevo recurso en caso de no existir. Idempotente*
PATCH Para cambiar el recurso parcialmente, o sea para cambiar soamente algunos valores del recurso
DELETE Para eliminar un recurso Idempotente*

* Idempotente: es la propiedad que indica que en caso de realizarse la misma operación varias veces sobre el mismo recurso, el resultado será el mismo en cuanto al estado del sistema (por ejemplo, si bien la respuesta a un delete es 201 la primera vez, la siguiente será 404 porque el recurso ya no existe, sin embargo, el estado del sistema es el mismo ya que de una u otra manera el recurso ya no existe).

Algunas consideraciones para tomarse en cuenta a la hora de realizar una API REST:
  • Los URI deben ser plurales, y para separar varias palabras utilizar '-' o camelCase (No importa cual se utilice, pero mantener a través de la API el mismo estilo).
  • Debe existir una clara separación de funciones (backend y frontend)
  • No se debe guardar estado entre peticiones (requests), no debe existir una sesión que almacene datos sobre la interacción del usuario.
  • Se debe mantener una cache para aminorar la carga de la red e incrementar el rendimiento de la aplicación.
  • Dada su arquitectura, es ideal para tener capas (cache, load balancer, proxy, cdn). El cliente no puede determinar si esta comunicandose directamente al servidor o a un software intermedio.
  • Es necesario tener una interfaz uniforme (no importa que convenciones se tenga, mantenerlas en toda la API)
  • Al decir creación de un recurso, no siempre se implica que se este creando un dato en la base de datos, pueden existir apis que de hecho no utilicen una Base de Datos, sin embargo, no es necesario ser tan "puritanos" al respecto :) 
En el caso de las respuestas de una API REST, las más comunes son:

  • 200 (ok), código básico que indica que la operación se realizo de forma exitosa
  • 201 (created), indica que el recurso se ha creado correctamente, es una típica respuesta de una petición POST o una petición PUT que ha creado un recurso.
  • 204 (no content), se utiliza típicamente para una petición que ha sido exitosa pero no existe ningún contenido para mostrar. Comunmente se utiliza como respuesta a un DELETE exitoso.
  • 400 (bad request), código que indica que ha ocurrido un error al procesar la petición (el usuario no debe vovler a realizar la petición sin haber modificado antes sus parámetros)
  • 401 (unauthorized), se utiliza para indicarle al usuario que sus credenciales con erroneas.
  • 403 (forbidden), indica que, si bien se sabe quien eres, no tienes los permisos para consumir el recurso en específico.
  • 404 (not found), código utilizado para señalar que el recurso no existe.
  • 500 (internal server error), se utiliza para señalar que ha ocurrido un error no previsto en la aplicación, del cuál no se puede dar un detalle más específico.


Algunos ejemplos :

- Obtener el detalle de un usuario en particular (usuario con id esteban)

http://api.rest.com/usuarios/esteban

- Obtener un listado de usuarios 

http://api.rest.com/usuarios

- En caso de paginación, es necesario utilizar dos parámetros en el uri, uno que indica cuantos datos se desea obtener y el otro desde que registro; además, en caso de ser necesario se puede enviar el total de datos como un header especial que comienze con X para indicar que es un header especial (por ejemplo X-Total-Registros o cualquier otro nombre, pero comenzando con X).
Si queremos obtener 10 registros a partir del registro 30, de un total de 100 registros, podriamos utilizar cualquiera de los siguientes ejemplos, pero es importante mantener el mismo estilo para todos los recursos de la API:

http://api.rest.com/usuarios?intervalo=30&limite=10

http://api.rest.com/usuarios?pagina=3&por_pagina=10

- En caso de búsquedas, existen dos opciones de acuerdo a la necesidad. Para búsquedas simples se pueden realizar sobre el mismo recurso, por ejemplo para buscar un usaurio cuyo nombre es Juan Perez:

http://api.rest.com/usuarios?nombre=juan%20perez

Sin embargo, en caso de busquedas avanzadas, y para no complicar demasiado una ruta, se puede utilizar un recurso llamado busquedas, y tanto un verbo GET como POST (con POST, estariamos creando un recurso llamado búsqueda). Por ejemplo con get, si queremos buscar al usuario con nombre juan peres y con edad mayor a 30(tomar en cuanta que > se códifica como %3e)

http://api.rest.com/busquedas?nombre=juan+perez&edad=%3e30

Con POST, podemos mandar datos en el cuerpo del mensaje y hacerlo más legible (recuerden que no es posible hacerlo de muchas maneras, pero lo mejor es mantenerlo consistente en la API):

http://api.rest.com/busquedas
body:
{
  "nombre": "juan perez",
  "edad": {
    "gt": 30
  }
}

Y eso es todo por ahora!!! en próximos posts extenderé el tema, keep coding >_<

No hay comentarios:

Publicar un comentario