jueves, 17 de diciembre de 2020

Diseño de un api ReST (III)

Continuamos con la serie de posts sobre apis ReST dedicándole una entrada a los parámetros en una petición (cero emoción).


Filtrado de recursos

Hemos visto que una petición GET a un servicio REST tendrá como respuesta un único recurso si se indica el identificador al final de la ruta o todos los contenidos en ella si termina en directorio. Se hace necesario un método por el cual los clientes puedan definir exactamente cuales son recursos que solicita.


Típica entrega de 500.000 recursos cuando no se han filtrado los resultados


HTTP cuenta con una herramienta para filtrar que recursos serán afectados por el método: la ‘query string’. Se trata de una sucesión de pares clave-valor con una sintaxis simple que se coloca a continuación de la ruta, después de una interrogación:

GET /ruta?Param1=valor1&param2=valor2&param3=valor3

El significado de esta petición es ‘los recursos contenidos en el directorio cuyas propiedades coincidan con los valores incluidos en la query’. Por ejemplo:

GET /clientes?estado=activo - Del directorio ‘clientes’ queremos solo aquellos cuyo estado sea ‘activo’

GET /facturas?fecha=17/7/2020 - Del directorio ‘facturas’ solo queremos las del 17 de julio.

DELETE /pedidos?estado=cancelado - Queremos que se eliminen solo los pedidos cancelados.

PUT /productos?estado=descatalogado - Queremos modificar los productos descatalogados 

Naturalmente habrá que programar la lógica de control necesaria en el lado del servidor para buscar estos parámetros en la petición y actuar en consecuencia cuando se encuentren. También será necesaria lógica para que cuando esos parámetros no estén presentes la petición sea rechazada (también se puede  devolver una cantidad limitada de recursos o implementar una paginación)

-Aquí está su respuesta, ¡con extra de JSON!


Seleccionando por criterios distintos a 'igual a'

Cuando se filtran resultados lo habitual es utilizar parámetros que coincidan con las propiedades de los recursos, pero no siempre es posible. Por ejemplo, si queremos entregar facturas entre dos fechas no encontramos una propiedad en los recursos ‘factura’ que nos sirva puesto que las facturas simplemente tienen ‘fecha’. Tenemos algunas opciones:

Utilizar parámetros creados específicamente para la búsqueda:

GET /facturas?fechaInicio=<fecha_inicio>&fechaFin=<fecha_fin>

Utilizar parámetros asociados con propiedades existentes, pero utilizando alguna sintaxis especial:

GET /facturas?fecha=gte:<fecha_inicio>,lte:<fecha_fin>

GET /facturas?fecha[gte]=<fecha_inicio>,fecha[lte]=<fecha_fin>

GET /facturas?fecha=gte:<fecha_inicio>,&fecha=lte:<fecha_fin>

Estos últimos tres ejemplos son igual de válidos, pero hay que tener en cuenta que la lógica para procesar esos parámetros en el servidor será tediosa de implementar (y fácil)


Otros usos

El uso principal de los parámetros es el de filtrar con más precisión los resultados que entregará el servidor al cliente pero podemos darle otros sin salirnos del camino que marca el protocolo HTTP. Recordemos que si lo abandonamos la cosa no será REST.

Estos usos exigen una implementación más compleja en el lado del servidor pero como se trata de cosas muy concretas e independientes del api en si se pueden generalizar e introducir en una librería reutilizable.


-Y ahora con un for revisas uno a uno los recursos a ver si cumplen el criterio de filtrado
-¿No lo hago mejor con el select?
-¿Se puede poner un for en el select?


Utilizando los parámetros para filtrar las propiedades de los recursos

Permite a los clientes indicar al servidor cuales propiedades de los recursos necesitan y minimizar así el trasiego de información y el consumo de memoria.

Tenemos libertad a la hora de definir el parámetro pero es habitual que tenga un nombre concreto que se puede utilizar en distintas peticiones y que sea de tipo múltiple. Por ejemplo

GET /libros?propiedades=id,titulo,autor

Con la adecuada implementación en el lado del servidor esta petición tendría como respuesta una lista de libros con los valores id, título y autor aunque el recurso tuviera muchos más valores.


Ordenando los resultados

Otro uso que puede darse a los parámetros es el de proporcionar a los clientes una manera de solicitar al servidor los recursos en un orden concreto. Debemos idear una sintaxis para el parámetro, existiendo muchas posibilidades. Los siguientes ejemplos son variaciones típicas y necesitan aproximadamente el mismo código en el servidor para extraer los valores:

GET /peliculas?orden=asc(titulo)

GET /peliculas?orden=desc(titulo)

GET /peliculas?orden=+titulo

GET /peliculas?orden=-titulo

También podríamos permitir varios campos para la ordenación. Quizás para esto sea más recomendable la segunda opción, con el más y el menos para poder alternan con más facilidad entre orden ascendente y descendente.

GET /productos?orden=+existencias,-precio


-Y aquí hemos puesto estas movidas para ordenar los resultados en el servidor
-¿Y cómo son esas movidas?
-Gordísimas

Y basta ya de parámetros. En el siguiente post continuaremos con más REST.








1 comentario:

  1. Esta serie de post es lo más grande que he leído desde que Terry Pratchett se pasó a la novela romántica.

    ResponderEliminar