====== 03_1 - API REST ====== Cualquier aplicación web se basa en una arquitectura cliente-servidor, donde un servidor queda a la espera de conexiones de clientes, y los clientes se conectan a los servidores para solicitar ciertos recursos. Estas comunicaciones se realizan mediante un protocolo llamado **HTTP** (o **HTTPS**, en el caso de comunicaciones seguras). En ambos casos, cliente y servidor se envían cierta información estándar, en cada mensaje: * Los clientes envían al servidor los datos del recurso que solicitan, junto con cierta información adicional, como por ejemplo las cabeceras de petición (información relativa al tipo de cliente o navegador, contenido que acepta, etc), y parámetros adicionales llamados normalmente datos del formulario. * Por lo que respecta a los servidores, aceptan estas peticiones, las procesan y envían de vuelta algunos datos relevantes, como un código de estado (indicando si la petición pudo ser atendida satisfactoriamente o no), cabeceras de respuesta (indicando el tipo de contenido enviado, tamaño, idioma, etc), y el recurso solicitado propiamente dicho, si todo ha ido correctamente. Para solicitar los recursos, los clientes se conectan o solicitan una determinada //URL// (siglas en inglés de //localización uniforme de recursos//, **Uniform Resource Location**). Esta URL consiste en una línea de texto con tres secciones diferenciadas: * El **protocolo** empleado (HTTP o HTTPS) * El **nombre de dominio**, que identifica al servidor y lo localiza en la red. * La **ruta** hacia el recurso solicitado, dentro del propio servidor. Esta última parte también suele denominarse URI (identificador uniforme de recurso, o en inglés, Uniform Resource Identifier). Esta URI identifica unívocamente el recurso buscado entre todos los demás recursos que pueda albergar el servidor. Por ejemplo, la siguiente podría ser una URL válida: ;#; http://miservidor.com/books?id=123 ;#; El protocolo empleado es //http//, y el nombre de dominio es //miservidor.com//. Finalmente, la ruta o //URI// es //books?id=123//, y el texto tras el interrogante '?' es la información adicional llamada datos del formulario. Esta información permite aportar algo más de información sobre el recurso solicitado. En este caso, podría hacer referencia al código del libro que estamos buscando. Dependiendo de cómo se haya implementado el servidor, también podríamos reescribir esta URL de este otro modo, con el mismo significado: ;#; http://miservidor.com/books/123 ;#; ===== Los servicios REST ===== **REST** son las siglas de **REpresentational State Transfer**, y designa un estilo de arquitectura de aplicaciones distribuidas, como las aplicaciones web. En un sistema //REST//, identificamos cada recurso a solicitar con una URI (identificador uniforme de recurso), y definimos un conjunto delimitado de comandos o métodos a realizar, que típicamente son: * **GET**: para obtener resultados de algún tipo (listados completos o filtrados por alguna condición) * **POST**: para realizar inserciones o añadir elementos en un conjunto de datos * **PUT**: para realizar modificaciones o actualizaciones del conjunto de datos * **DELETE**: para realizar borrados del conjunto de datos Existen otros tipos de comandos o métodos, como por ejemplo **PATCH** (similar a //PUT//, pero para cambios parciales), **HEAD** (para consultar sólo el encabezado de la respuesta obtenida), etc. Nos centraremos, no obstante, en los cuatro métodos principales anteriores. Por lo tanto, identificando el recurso a solicitar y el comando a aplicarle, el servidor que ofrece esta //API REST// proporciona una respuesta a esa petición. Esta respuesta típicamente viene dada por un mensaje en formato **JSON** o **XML** (aunque éste último cada vez está más en desuso). Durante la realización de la mayoría de las prácticas del curso, usaremos una aplicación llamada [[https://www.postman.com/|Postman]], que permite construir peticiones de diferentes tipos, empleando distintos tipos de comandos, cabeceras y contenidos, enviarlas al servidor que indiquemos y examinar la respuesta proporcionada por éste. ===== JSON ===== **JSON** son las siglas de **JavaScript Object Notation**, una sintaxis propia de Javascript para poder representar objetos como cadenas de texto, y poder así serializar y enviar información de objetos a través de flujos de datos (archivos de texto, comunicaciones cliente-servidor, etc). Un objeto Javascript se define mediante una serie de propiedades y valores. Por ejemplo, los datos de una persona (como nombre y edad) podríamos almacenarlos así: let persona = { nombre: "Nacho", edad: 39 }; Este mismo objeto, convertido a JSON, formaría una cadena de texto con este contenido: { "nombre": "Nacho", "edad": 39 } Del mismo modo, si tenemos una colección (vector) de objetos como ésta: let personas = [ { nombre: "Nacho", edad: 39 }, { nombre: "Mario", edad: 4 }, { nombre: "Laura", edad: 2 }, { nombre: "Nora", edad: 10 } ]; Transformada a JSON sigue la misma sintaxis, pero entre corchetes: [ { "nombre": "Nacho", "edad": 39 }, { "nombre": "Mario", "edad": 4 }, { "nombre": "Laura", "edad": 2 }, { "nombre": "Nora", "edad": 10 } ] ===== Códigos de estado ===== Los códigos de estado de la respuesta, depende del resultado de la operación que se haya realizado. Se catalogan en cinco grupos: * **Códigos 1XX**: representan información sobre una petición normalmente incompleta. No son muy habituales, pero se pueden emplear cuando la petición es muy larga, y se envía antes una cabecera para comprobar si se puede procesar dicha petición. * **Códigos 2xx**: representan peticiones que se han podido atender satisfactoriamente. El código más habitual es el 200, respuesta estándar para las peticiones que son correctas. Existen otras variantes, como el código 201, que se envía cuando se ha insertado o creado un nuevo recurso en el servidor (una inserción en una base de datos, por ejemplo), o el código 204, que indica que la petición se ha atendido bien, pero no se ha devuelto nada como respuesta. * **Códigos 3xx**: son códigos de redirección, que indican que de algún modo la petición original se ha redirigido a otro recurso del servidor. Por ejemplo, el código 301 indica que el recurso solicitado se ha movido permanentemente a otra URL. El código 304 indica que el recurso solicitado no ha cambiado desde la última vez que se solicitó, por si se quiere recuperar de la caché local en ese caso. * **Códigos 4xx**: indican un error por parte del cliente. El más típico es el error 404, que indica que estamos solicitando una URL o recurso que no existe. Pero también hay otros habituales, como el 401 (cliente no autorizado), o 400 (los datos de la petición no son correctos, por ejemplo, porque los campos del formulario no sean válidos). * **Códigos 5xx**: indican un error por parte del servidor. Por ejemplo, el error 500 indica un error interno del servidor, o el 504, que es un error de timeout por tiempo excesivo en emitir la respuesta. En este [[https://www.ibm.com/docs/es/odm/8.5.1?topic=api-rest-response-codes-error-messages|enlace]] puedes ver los diferentes código de estado y su explicación. Haremos uso de estos códigos de estado en nuestros servicios REST para informar al cliente del tipo de error que se haya producido, o del estado en que se ha podido atender su petición. ===== Endpoints ===== un **endpoint** se refiere a una URL específica a la que se puede realizar una solicitud HTTP (GET, POST, PUT, DELETE...) para interactuar con un recurso o conjunto de recursos. Cada endpoint está asociado con una operación y puede devolver o manipular datos en formato JSON, XML u otro formato, según lo definido por la API. Hay una serie de buenas prácticas a la hora de crear tus endpoints. Algunas de ellas son: * Deberían siempre ser sustantivos, nunca verbos. El tipo de acción (el verbo) viene determinado por el método HTTP (GET, PUT, POST, DELETE...). * Los recursos tienen que estar en plural, aunque se devuelva uno sólo. * Para relacionar recursos, se van anidando recursos específicos en la URL. Vamos a ver varios ejemplos para clarificar lo anterior: * GET /books - Devuelve el listado de todos los libros. * GET /books/12 - Devuelve el libro con id 12. * POST /books - Crea un nuevo libro * PUT /books/12 - Actualiza el libro con id 12. * DELETE /books/12 - Elimina el libro con id 12 * GET /books/12/authors - Devuelve el listado de autores del libro con id 12. Más adelante ya veremos como enviar los datos que tenemos que insertar o borrar. Además, los endpoints pueden llevar parámetros opcionales. Por ejemplo, el siguiente endpoint devolvería la página 3 del listado de libros: ;#; GET /books?page=3 ;#;