Mostrando entradas con la etiqueta JSON. Mostrar todas las entradas
Mostrando entradas con la etiqueta JSON. Mostrar todas las entradas

lunes, 5 de octubre de 2020

Diseño de un api ReST (II)

Continuamos la serie sobre apis ReST. En el anterior post vimos el papel que tiene el protocolo HTTP y el significado de los métodos, así como ejemplos de las urls más sencillas. Con estos rudimentos podemos construir nuestra api, en un ejemplo en el que el recurso serán los clientes en una aplicación de gestión.


El recurso

Los recursos cliente de nuestro ejemplo tendrán las siguientes propiedades (a modo de muestra)

  • id: numérico, es un identificador único para cada cliente
  • nombre, cadena de texto
  • direccion, cadena de texto
  • telefono, cadena de texto

El api

Antes de definir un api debemos conocer lo que se esperan las aplicaciones clientes de nuestro servicio y cuales son los requisitos de la aplicación que lo publica. Vamos a suponer que en nuestro caso es necesario un mantenimiento básico de los datos de los clientes, con las siguientes funcionalidades:

  • Generación de listados de clientes
  • Búsqueda de un cliente
  • Alta de un nuevo cliente
  • Modificación de un cliente
  • Baja de un cliente

-Nada que ver aquí, es solo un CRUD


GET /clientes

Devuelve el contenido del directorio ‘clientes’. Aquí hay una idea importante: lo que debe devolver una petición GET será lo contenido en la última carpeta de la ruta si no se adjunta un identificador. ¿Y si hay muchos clientes? Pues mientras no filtremos los resultados deberán devolverse todos. Más adelante hablaremos de cómo debe expresarse el filtrado de resultados en un api ReST





Vemos que al solicitar clientes con GET nos envían un documento JSON con la representación del estado actual de los clientes en el servidor.


-¿Asi que eso es lo que significa representational state transfer?


GET /clientes/{id}

Devuelve el recurso contenido en el directorio ‘clientes’ cuyo identificador es ‘id’. ¿Y si no existe un recurso con ese identificador? Otro punto importante aquí: todas las respuestas que de el servidor deben incluir el código de respuesta HTTP adecuado. En este caso debería ser 404 NOT FOUND en lugar de un 200 OK.

Podría pensarse que para solicitar un único cliente debiera ser ‘GET /cliente/{id}’ pero esto no es así. El protocolo HTTP habla de recursos que están en directorios y los clientes están en ‘clientes’. Es una regla: los directorios guardan muchos recursos, los directorios están en plural. Es más: la petición ‘GET /clientes/{id}’ ha de interpretarse como ‘entra en el directorio clientes y localiza el recurso cuyo id es el indicado’.



POST /clientes

Insertará un recurso nuevo en el directorio ‘clientes’. De nuevo nos encontramos con asuntos destacables. El nuevo recurso deberá adjuntarse como contenido en el cuerpo de la petición HTTP, en el formato que el servidor espere o soporte. Como respuesta a una petición post es buena idea entregar el recurso tal y como ha quedado en el servidor, su id o un enlace a él.




PUT /clientes/{id}

Localiza el recurso cuyo id se indica en la ruta y lo sustituye por el que se haya proporcionado con la petición. Si el recurso no existiera es elección del servidor el devolver un 404 o crear un nuevo recurso.


En la petición el identificador del cliente a sustituir está en la ruta. En este ejemplo tambien lo vemos en el documento json del cuerpo. Esto es habitual, ya que las aplicaciones cliente suelen generar el json a partir de objetos en memoria y no se molestan en eliminar propiedades no solicitadas. El servidor utilizará solo el id de la ruta y deberá ignorar completamente cualquier otro. 


PATCH /clientes/{id}

PATCH fue añadido a HTTP en 2010. Es similar a PUT salvo que mientras PUT sustituye un recurso por otro PATCH modifica el existente. Esto implica que en una petición PATCH puede adjuntarse una representación parcial del recurso que incluya únicamente los valores que han de cambiar.


En la petición el identificador del recurso forma parte de la ruta (el recurso identificado con '25' del directorio 'clientes') y en el cuerpo de la petición solo se indica las propiedades que cambian. En la respuesta (y esto es opcional) se incluye el recurso entero tal y cómo ha quedado. 


DELETE /clientes/{id}

Esta petición solicita la eliminación del recurso identificado por ‘id’, que está en el directorio ‘clientes’.  Si el recurso se ha podido eliminar la respuesta será un 200 OK si queremos indicar algo al cliente (en el body de la respuesta) o 204 NO CONTENT si la simple respuesta 2XX basta. Si el recurso no existiera debería devolverse un 404 NOT FOUND.
Una petición DELETE que no incluya el identificador del recurso debería afectar a todos los recursos del directorio, es decir: ‘DELETE /clientes’ debería tener como resultado la eliminación de todos los clientes.  




Ya tenemos la base del diseño de un api ReST, pero aun faltan algunos temas importantes. Continuaremos hablando de ello en el siguiente post.


Esperando la respuesta a una petición GET

lunes, 21 de septiembre de 2020

Diseño de un api ReST

En la actualidad existen muchas tecnologías para publicar servicios y componer una arquitectura cliente-servidor. ReST es probablemente la más extendida y es difícil encontrar un sitio en el que no se esté usando. En este post veremos las bases de ReST y explicaremos como diseñar un api que sea aceptablemente ortodoxa.


Cables azules para las peticiones GET. Cables blancos para las POST


El protocolo HTTP

La idea que hay detrás del protocolo HTTP es sencilla y particular: en un servidor existen una serie de recursos guardados en directorios reales o imaginarios. Después los clientes envían peticiones en las que se incluye una ruta a uno o varios de esos recursos junto con un verbo que indica que acción debe realizarse una vez estos hayan sido localizados.

Otras características de HTTP que lo hacen muy conveniente como protocolo de comunicación entre cliente-servidor son:
  • Mensajes sencillos: Los mensajes HTTP son textos planos con apenas estructura. Una cabecera con información sobre la petición y un cuerpo opcional. Es tan sencillo que la separación entre cabecera y cuerpo son dos saltos de línea y retorno de carro seguidos.
  • Independiente del formato de la información intercambiada. Puede ser xml, json, una imagen, html o cualquier cosa que se nos pase por la cabeza.
  • Sin estado: La conversación más larga que puede mantenerse con HTTP es petición-respuesta, precisamente porque HTTP está pensado para aplicaciones distribuidas que trabajan con los recursos alojados en un servidor. El servidor no almacenará estado alguno ni dedicará recursos en ello (por ejemplo creando sesiones). Si es necesario mantener un estado esta tarea recaerá sobre las aplicaciones cliente.

Esta última característica tiene una gran importancia a la hora de diseñar un api ReST y todas las funcionalidades que ofrezca el servidor deberán tenerla en cuenta.


ReST

De Representational State Transfer, es una arquitectura de software para aplicaciones cliente-servidor ideada por Roy T. Fielding cuya principal característica es que utiliza el protocolo HTTP hasta la última consecuencia. Toda la información que maneje el servidor será representada como recursos y cualquier funcionalidad ofrecida por este deberá poder accederse a través de una petición HTTP que respete los principios del protocolo al pie de la letra. 

Roy T. Fielding diciendo lo que es ReST y lo que no.

Los recursos

Lo primero que definiremos cuándo diseñamos un api ReST son los recursos. Estos serán la información que maneje nuestro servicio. Ejemplos típicos (y tópicos) de recursos podrían ser clientes, facturas, productos, empleados... Cada uno de estos recursos deberá identificarse con un valor único y poseerá distintas propiedades. Por ejemplo: los clientes tendrán id, nombre, DNI, fecha de nacimiento y los productos id, referencia, fabricante, peso, etc.

Decidir cuáles son los recursos resulta más sencillo cuando ya disponemos de una base de datos o la lógica de la aplicación. Es la norma que exista una relación entre las tablas que tengamos y los recursos del servicio. Esto también ocurrirá con respecto a las entidades que utilice nuestra lógica de negocio. Además descubriremos que las relaciones entre esas tablas o entidades se ve reflejada en las relaciones existentes entre los recursos. Pero no nos confundamos: ¡un api ReST es una abstracción que a simple vista nada tiene que ver con un diagrama de clases o de entidad-relación!


La representación de los recursos

Una vez identificados los recursos debemos decidir cómo los representaremos en las peticiones y respuestas. HTTP permite cualquier formato, pero normalmente podremos escoger entre XML y JSON debido a que los frameworks suelen tener en cuenta únicamente esos dos formatos. Si escogemos otra manera de representar a los recursos nos tocará hacer las debidas conversiones con nuestro propio código.

La inmensa mayoría de servicios ReST trabajan con JSON puesto que contienen la misma información que un XML pero son más sucintos, a costa de no incluir ninguna descripción de la información que contienen. Veámoslo con un ejemplo:

Lucha de acrónimos

En el XML vemos que hay claramente una lista de clientes. En JSON básicamente sustituimos cada etiqueta xml por un único carácter. Cierto que no queda claro que se trate de clientes y bien pudieran ser ‘empleados’ o ‘personas’ pero no debemos olvidar que en un servicio ReST tenemos una aplicación cliente que es capaz de saber que está solicitando un listado de clientes, no de empleados. El XML en este caso es un despilfarro de ancho de banda.

Las rutas

El siguiente paso una vez que conozcamos cuáles son nuestros recursos será definir las rutas para localizarlos. Debemos ‘colocarlos’ en esos directorios de los que nos habla el protocolo HTTP y es el momento de hacer un inciso relacionado con ellos.
En HTTP localizamos los recursos utilizando URLs. Con una URL identificamos un recurso, su localización y el modo en el que accederemos a él.



En la ruta encontramos los directorios en los que se localiza el recurso identificado por el valor final. Cuando se trata de recursos físicos esos directorios existen realmente. Es lo que sucede, por ejemplo, con un servidor web. En Apache (el servidor web más utilizado) disponemos del directorio ‘www’ dentro del cual organizamos nuestros ficheros .html, .css, imágenes y demás cacharrería. Cuando los recursos son abstractos, representaciones de filas en una tabla u objetos en la memoria del servidor, los situaremos en directorios ficticios para ‘seguirle el juego’ al protocolo HTTP.


Recursos físicos en un servidor Apache de color azul


Una técnica que nos ayuda a definir las rutas es imaginarnos los recursos realmente como ficheros y realizarnos la siguiente pregunta: Si tuviera una serie de ficheros, a razón de uno por ‘Empleado’ ¿en qué directorio los guardaría? ¿Y si fueran facturas, productos o cualquier otra cosa? La respuesta es clara: en los directorios ‘empleados’, ‘facturas’ y ‘productos’.

Los métodos

En HTTP una petición es una ruta a los recursos más una acción, el método. De todos los métodos definidos en HTTP los cinco que sirven para actuar sobre los recursos son

  • GET: se solicitan recursos existentes en el servidor
  • POST: añade un nuevo recurso en la ruta indicada
  • PUT: Sustituye el recurso indicado por la url por el que se envía. Si no existe lo añadirá.
  • PATCH: Modifica el recurso utilizando los datos adjuntos a la petición.
  • DELETE: Elimina los recursos indicados en la url.

En realidad los métodos no hacen nada…todo depende de la implementación del servicio en el lado del servidor. Vamos a suponer que nadie programará que al recibir un GET se elimine un recurso y que cuando se reciba un DELETE se entregen. Suena absurdo, pero es perfectamente posible hacerlo así.

Con esto ya tenemos la base de que es un servicio ReST. En el siguiente post comenzaremos con el diseño de un api sencilla.


Jordan Peterson después de haber leído este artículo





miércoles, 10 de junio de 2020

Tecnologías web 103

Más frameworks, ahora para CSS también

Llegamos al ecuador de nuestra serie de posts sobre las tecnologías web, ya hemos visto en el primer post Tecnologías Web 101 los inicios de la web, y en el segundo, Tecnologías Web 102, vimos como empiezan a aparecer los primeros frameworks tanto del backend como del frontend.

Pues como no hay dos sin tres, aquí está el tercer post donde veremos como aparecen los primeros frameworks del CSS, la llegada de los componentes web, hasta llegar a la estandarización de un formato que ya se venía usando.


Diseños flexibles


El año 2011 fue el año del CSS. En este año salió CSS3 que traía novedades en el sistema de layout de las páginas. Aparecen Flexbox y Grid Layout que nos permiten crear plantillas flexibles y definir filas y columnas de una forma sencilla reduciendo el uso de la propiedad float que tanta guerra ha dado, y favoreciendo el diseño responsive de las aplicaciones.

A parte de CSS3, también empiezan a salir los frameworks de estilos como Bootstrap (de Twitter) y Foundation (de Zurb) que nos proporcionan una cantidad muy grande de estilos asociados a unas clases predefinidas y que nos hará muy fácil cambiar la apariencia de nuestras aplicaciones. También definen un sistema de columnas que van a facilitar hacer que las aplicaciones se adapten a los distintos tipos de dispositivos.

Uno para todos y todos para uno


Este mismo año Alex Russell introduce los Web Components en la comunidad, una idea influenciada por las directivas de AngularJS que va a permitir la creación de nuevas etiquetas HTML con una estructura y funcionalidad definida y que se pueden reutilizar entre distintas aplicaciones de una forma sencilla.


Por otro lado Google presenta un nuevo lenguaje para la web como alternativa a JavaScript que se viene usando desde los inicios, este lenguaje es Dart, y está pensado para solucionar algunos de los problemas que nos podemos encontrar con JS. Pero no tuvo una fuerte acogida por parte de los desarrolladores que preferían seguir usando JavaScript, y por ello se desecharon los planes que tenía Google para integrar de forma nativa en su navegador una máquina virtual para ejecutar el código y los cambiaron por crear una herramienta para compilar Dart a JavaScript.

Además surgen otros dos framework.

EmberJS para el frontend, permitiéndonos hacer SPAs, donde dos de sus principales características son las que se siguen con Ruby on Rails, COC y DRY. También incorpora un cli que va a hacer que la productividad aumente proporcionando una forma sencilla y rápida para generar servicios, instalar plugins... Y con el podíamos usar las últimas novedades de JavaScript haciendo uso de Babel para transpilar el código. De este framework se ha llegado incluso a grabar un documental.

En cuanto al otro framework, es Laravel, un framework de PHP. En la actualidad es uno de los frameworks de PHP más usados, junto a Symfony mencionado anteriormente. Viene a proporcionarnos un método sencillo y rápido de construir aplicaciones web, en el que la curva de aprendizaje es muy cómoda.



Durante el siguiente año, Microsoft presenta un nuevo lenguaje de programación basado construido sobre JavaScript, el cual nos va a permitir usar características comunes en otros lenguajes y que JavaScript no permite, como el tipado estático o las interfaces. Este nuevo lenguaje es TypeScript, y vamos a poder usarlo tanto para el cliente como para el servidor, aunque en realidad el código final que se va a ejecutar en estos entornos será JavaScript. Por tanto, necesitamos transpilar el código de TS para obtener el código equivalente en JS.


La ventaja de usar TypeScript frente a JavaScript es que a la hora de transpilar el código se nos van a mostrar errores, sobre todo errores de tipado, de tal forma que nuestro código final será más robusto.



Este mismo año, surge un framework web fullstack llamado Meteor que permite crear aplicaciones web, móviles y de escritorio, de una forma muy rápida. Por defecto, como BBDD usa MongoDB, el servidor está montado con Node y para el frontend al principio usaba Blaze como motor de plantillas, pero según han ido apareciendo nuevas librerías han ido añadiendo más opciones como React o Vue. Pero una de las novedades más importantes que trae este framework es la actualización de los datos en tiempo real, es decir, que si abres la misma página desde distintos dispositivos y se añade algún dato nuevo, este aparecerá en todos los dispositivos automáticamente sin necesidad de refrescar la página.

Tras la aparición de frameworks como AngularJS o Backbone que nos permiten crear SPAs y el uso de los dispositivos móviles para entrar en las aplicaciones web, nos encontramos con que tenemos la aplicación dividida en varios archivos que se tienen que descargar, y cuantos más archivos que descargar haya, más peticiones hay que hacer, con lo que ello conlleva.

Aquí es donde entra Webpack, un module bundler que nos permite gestionar todos los recursos que se van a usar en la aplicación. Webpack va a ir aplicando unos loaders a nuestro código que lo va a ir transformando y uniendo hasta generar los archivos finales (un bundle.js). Por ejemplo, si estamos usando Sass, tendremos que transformar el código a CSS y para ello tendremos que aplicar el loader que se encarga de ello. También se encarga de minimizar el código, haciendo que los archivos que genera ocupen el menor espacio posible.



Para el año 2013 se estandariza el formato JSON que Douglas Crockford había especificado anteriormente. Este formato va a empezar a usarse junto a AJAX por sus ventajas, haciendo que los datos que se van a transferir pesen menos, por lo tanto tarden menos en comunicarse el servidor y el cliente, haciendo que la experiencia del usuario mejore. Los desarrolladores terminarán sustituyendo al XML por JSON en las peticiones AJAX.


Aquí terminamos por hoy. En el siguiente post, Tecnologías Web 104,  veremos como la llegada del iPhone hace que se empiece a pensar en el desarrollo responsive, y el desarrollo multiplataforma.