====== 4. El protocolo HTTP ====== El protocolo HTTP se usa para enviar y recibir datos en la Web. En los siguientes enlaces se hace una explicación de HTTP: * [[https://developer.mozilla.org/es/docs/Web/HTTP/Overview|Generalidades del protocolo HTTP]]: Explicación del HTTP * [[https://blog.makeitreal.camp/el-protocolo-http/|El protocolo HTTP]]: Otra explicación del HTTP ===== Características ===== * Sencillo: Es en modo texto y sacil de usar directamente por una persona. * Extensible: Se pueden enviar mas metadatos que los que estan por defecto. Ej: Nº de página * Sin estado: Cada petición es independiente. Eso es un problema en sitios como por ejemplo un carrito de la compra. ===== Ventajas ===== * Cache: Mejora la velocidad al controlar la cache de las páginas * Autenticación: Permite identificar a un usuario * Proxys: Permite de forma transparente usar proxies * Sesiones: Gracias a las cookies podemos mantener el estado entre peticiones. * Formatos: Permite indicar el formato de lo que se envía, de lo que se pide y de lo que se retorna. ===== Formato ===== El formato lo vamos a explicar sobre un ejemplo. Una petición HTTP tiene la siguiente forma: GET /index.html HTTP/1.1 Host: www.fpmislata.com Accept-Language: fr La respuesta del servidor es: HTTP/1.1 200 OK Content-Length: 29769 Content-Type: text/html; charset=utf-8 * La cabecera ''Content-Type'' es imporante para el programador ya que el servidor puede no saber exactamente el formato de los datos y es necesario que lo indiquemos nosotros.Muchas veces hay ademas problemas con la codificación si es ''utf-8'' o ''ISO-8859-1'' por lo que también se debe indicar. * Por otro lado notar que ''Content-Type'' se puede usar tanto en la petición como en la respuesta. Se usa en la petición si se envían datos en la petición ===== Estados HTTP ===== Es estado es lo que indica si una petición HTTP ha tenido éxito o no. Sus principales valores son: * 200-299: La petición ha tenido éxito * 300-399: Redirección de los datos. * 400-499: Los datos que ha enviado el cliente no son correctos * 500-599: Se ha producido un error en el servidor. Mas información en [[https://es.wikipedia.org/wiki/Anexo:C%C3%B3digos_de_estado_HTTP|Códigos de estado HTTP]] De entre todos los código están algunos que solemos ver a menudo: * 204: La petición no retorna datos. * 403: Prohibido el acceso al documento * 404: No encuentra el documento * 500: Error del servidor ===== Métodos ===== Los métodos ( o verbos) HTTP indican que acción queremos hacer con los datos. Al navegar normalmente se usa siempre el ''GET''. * ''GET'': Queremos obtener los datos * ''POST'': Queremos añadir los datos. * ''PUT'': Queremos actualizar nuevos datos. * ''DELETE'': Queremos borrar los datos. Así por ejemplo si enviamos; GET /index.html HTTP/1.1 Host: www.fpmislata.com Accept-Language: fr Obtendremos el fichero ''index.html'' pero si enviamos: DELETE /index.html HTTP/1.1 Host: www.fpmislata.com Accept-Language: fr El servidor **borrará** el fichero ''index.html'', por lo que con ''POST'' podríamos añadir una nueva página y con ''PUT'' borrar una página. ===== REST ===== Podríamos decir que REST es usar toda la potencia de HTTP en nuestras propias aplicaciones. Suele usar Por forma general el formato usado en los datos es [[https://es.wikipedia.org/wiki/JSON|JSON]] , es muy sencilla y utiliza todas las características que puede de de HTTP en vez de reinventarse lo que ya tiene HTTP. Esta última característica yo creo que es la que mejor explica que es REST: Si algo ya existe en HTTP y REST siempre funciona bajo HTTP, ¿porque no usar entonces todo lo que ofrece HTTP?. Por lo tanto cuando necesitemos algo en nuestra aplicación siempre debemos preguntarnos , ¿como resuelve este problema ya el protocolo HTTP? Y usarlo en vez de crear nuestra solución. ==== Las operaciones a realizar ==== Vamos a ver 4 método HTTP que coinciden con los 4 métodos de un CRUD o con operaciones de SQL ^ Método HTTP ^ Descripción ^ Metodo CRUD ^ Metodo SQL ^ | GET | Este método HTTP lo usaremos para cuando queremos leer datos del servidor | Read | SELECT | | POST | Este método HTTP lo usaremos para añadir datos al servidor | Crear | INSERT | | PUT | Este método HTTP lo usaremos para actualizar ((realmente es actualizar o insertar pero en este curso por simplificar, el POST solo actualizará)) datos del servidor | Update | UPDATE | | DELETE | Este método HTTP lo usaremos para borrar datos del servidor | Delete | DELETE | ==== La Estructura de la URL ==== Veamos la estructura de la URL de las peticiones en un supuesto ejemplo de una base de datos de usuarios. ^ Descripción ^ URL ^ Método HTTP ^ JSON Enviado ^ JSON Retornado ^ | Obtener un libro | ''/libro/{idLibro}'' | GET | Ninguno | Libro leido | | Listado de libros | ''/libro'' | GET | Ninguno | Array de Libros | | Añadir un libro | ''/libro'' | POST | Libro a insertar | Libro insertado | | Actualizar un libro | ''/libro/{idLibro}'' | PUT | Libro a actualizar | Libro actualizado | | Borrar un libro | ''/libro/{idLibro}'' | DELETE | Ninguno | Ninguno | Donde pone ''{idLibro}'' se subtituiría por el id del libro. El "JSON Enviado" es el JSON que se debe enviar con los datos al hacer esa petición. Como podemos ver solo se envía al insertar o al actualizar. Es decir es el JSON del usuario a insertar o el JSON con los nuevo datos del usuario a modificar. El "JSON Retornado" es lo que nos retornará el servidor. Como vemos nos retorna un JSON con los datos en todos los casos excepto en el borrado, y no lo hace ya que no existe ningún dato a retornar ya que lo hemos borrado. ===== Servidor REST en NodeJS ===== Ahora vamos a ver como modificar nuestro servidor en NodeJS para poder leer y modificar cosas relacionadas con HTTP. El ejemplo contiene: * Leer cabeceras * Aceptar varios métodos * Retornar varios códigos de estado * Devolver cabeceras const express = require('express') const app = express() const port = 80 app.get('/', (request, response) => { response.set('Content-Type', 'text/plain'); response.status(200); if (request.header('Accept-Language').startsWith("ca-ES")) { response.send("Hola mon"); } else if (request.header('Accept-Language').startsWith("en-EN")) { response.send("Hello World"); } else { response.send("Hola mundo"); } }); app.post('/', (request, response) => { response.status(200); response.send('Hello from post!'); }); app.delete('/', (request, response) => { response.status(200); response.send('Hello from delete!'); }); app.delete('/libro/38', (request, response) => { response.status(200); response.send('Borrado libro 38'); }); app.delete('/libro/39', (request, response) => { response.status(404); response.send('El libro 39 no existe'); }); app.listen(port, (err) => { console.log(`server is listening on ${port}`) }) ===== Ejercicios ===== ==== Ejercicio 1 ==== Usando el programa [[https://www.putty.org/|putty]], puedes conectarte en con el tipo de conexión "raw" al puerto 80 de cualquier máquina y enviar texto al cualquier servidor. Debes conectarte al servidor "www.fpmislata.com" al puerto 80 y enviar el texto de una petición HTTP. Es decir escribir tal cual se envía una petición HTTP. * Envía la petición HTTP sin cabeceras. ¿Porque ha fallado? * Añade ahora la cabecera ''Host'' y vuelve a enviar la petición. ¿Porque ahora funciona?. Indica las cabeceras que ha retornado y los datos. * Haz una nueva petición a la URL "/wordpress/secretaria/novedades-secretaria/". Comprueba que todo funciona. ==== Ejercicio 2 ==== En tu máquina debes instalar lo siguiente: * Descargar el fichero {{biblioteca-original.json.zip|}} y descomprimelo. Mira el contenido del fichero ''biblioteca-original.json''. * Instala el servidor [[https://github.com/typicode/json-server|JSON Server]] npm install -g json-server * Ves al directorio donde está el fichero ''biblioteca-original.json'' y ejecuta: json-server --watch biblioteca-original.json * Navega a [[http://localhost:3000/libro/1]] y debes ver lo siguiente: { "id": 1, "title": "El señor de los anillos", "autor": 1, "genero": 1 } Indica las siguientes y datos: ^ Descripción ^ URL ^ Datos enviados al Servidor ^ Datos leidos del servidor ^ | Obtener el libro de "La fundación" | | | | | Borrar el libro de "Yo Robot" | | | | | Obtener todos los libros | | | | | Añadir un nuevo género llamado "Histórico" | | | | ==== Ejercicio 3 ==== Desde Firefox instala el plugin de [[https://addons.mozilla.org/es/firefox/addon/restclient/|RESTClient]] o desde Chrome el plugin [[https://chrome.google.com/webstore/detail/yet-another-rest-client/ehafadccdcdedbhcbddihehiodgcddpl|Yet Another REST Client]] Lanza las URL del ejercicio anterior. Si hay datos de entrada los deberás enviar en el campo de "Body" y añadir las cabeceras adecuadas ==== Ejercicio 4 ==== Modifica el servidor hecho en NodeJS de forma que: * En la URL ''/libro/3'' con un ''GET'' retorne los datos de un libro (Te tienes que inventar los datos). Deberá permitir que sean en JSON o XML dependiendo de la cabecera "Accept" y también habrá que tener en cuenta la cabecera ''Accept-Language'' , permitiendo la respuesta en castellano o inglés. * En la URL ''/libro/4'' con un ''GET'' indique que no existe ese usuario Este ejercicio **no** tiene nada que ver con el ejercicio del JSON Server, se hace todo sobre el código de NodeJS de express.