This graph shows how many times the word ______ has been mentioned throughout the history of the program.
Igual que compararse y de progresar, pues hoy vamos a progresar con el curso de Node.js.
Tenemos un repositorio. En el repositorio os voy a estar subiendo también los vídeos.
En este caso, ¿veis que he puesto el vídeo? A ver, os voy a cambiar el videíto, ¿vale?
Para que tengáis el correcto este, que además está editado y súper bonito.
Aquí tendréis todos los vídeos. Si en algún momento os perdéis alguno y queréis saber dónde está el vídeo y tal,
pues aquí no solo vais a tener los vídeos, sino que además tenéis el código.
O sea, que podéis ver el código de cada una de las clases. Aquí en clase 1 tenéis todos los ejemplos que hicimos aquí,
que está súper chulo. O sea, todos los ejemplos con todas las dependencias.
Así que si hay alguna cosa que no entendisteis, que no visteis, que tal, lo podéis mirar y ya está.
Clase del curso de Node.js desde cero. Hoy vamos a crear nuestra primera API desde cero.
Vamos a hacer un servidor web. Te voy a explicar cómo funciona el protocolo HTTP.
Qué es lo que viaja en la request, qué es lo que viaja en una response, cómo funcionan y qué información interesante tiene cada una.
Vamos a crear una API desde cero con Node.js sin dependencias para que veas cómo se haría y qué es lo que nos aporta,
cómo lo podemos crear, cómo podríamos intentar acercarnos en lo máximo a sin dependencias,
hacer una API, responder a diferentes rutas.
Y después vamos a ver cómo podríamos pasar a Express.
Y si nos da tiempo, vamos a hacer una cosa que te va a volar la cabeza.
Vamos a intentar, si nos da tiempo, es el hecho de que vamos a crear nuestra propia biblioteca .env.
.env, por si no lo sabes, es seguramente una de las bibliotecas más utilizadas del universo.
.env, para que no lo sepa, es para variables de entorno.
Y vas a ver que con todo lo que hemos aprendido en estas dos clases, la que hicimos el otro día y la de hoy,
vamos a poder crear nuestro propio .env para utilizarlo en cualquier proyecto, sin necesidad de instalar nada.
Y vas a decir, joder, pues sí que es fácil, sí que es fácil, ¿vale?
Así que, estate atento.
Vamos con el código, voy a abrir aquí el proyectito que tenía por acá, ¿vale?
Levantamos esto, ¿vale?
Ya tenemos por aquí esto.
Ah, vamos a ver un montón de cosas interesantes, ¿eh?
Por ejemplo, cómo utilizar Nodeemon, Watch y todo esto, ¿eh?
Vamos a crear la clase 2, clase 2 y arrancamos con nuestras clases, ¿vale?
Vamos a revisar antes un poco lo que, dónde lo dejamos.
Bueno, lo dejamos con este archivo porque creamos ya un servidor web,
donde importábamos con require utilizando common.js, que ya vimos que había dos tipos de módulo, ¿no?
enmascriptmodus y common.js.
Estábamos importando la dependencia de node2.http para poder trabajar con el protocolo HTTP,
poder crear un servidor y todo esto.
Aquí simplemente estamos mirando cómo utilizar las variables de entorno
para poder decirle qué puerto queríamos utilizar.
Aquí creamos el servidor, ¿ves?
HTTP.createServer y aquí hacemos un console.log de que habíamos recibido una request.
Hola mundo y ya está. Esto es todo lo que hicimos.
¿Dónde nos enfocamos?
Nos enfocamos en que hicimos esta pequeña biblioteca muy interesante
para encontrar el puerto libre que tenía nuestra máquina.
Que esto es una cosa que no se ve muchas veces y la gente utiliza una dependencia y ya está.
Pues nosotros lo hicimos desde cero para quitarle un poquito de magia.
Pero bueno, esto es lo interesante, ¿no?
Nos quedamos un poco aquí con este HTTP.
Vamos a empezar, si os parece, con este HTTP.js, la clase 2.
Nos lo vamos a copiar, ¿vale?
Y lo vamos a revisar un poco.
Vamos a ver cómo funciona.
Ahora tendríamos el HTTP aquí para encontrar el puerto disponible.
Lo vamos a quitar para simplificarlo, ¿vale?
Vamos a decir que sea un 2.3.4 por defecto.
Y aquí utilizamos el puerto disponible.
Aquí el desire port lo vamos a poner aquí, ¿vale?
Y vamos a explicar un poco el código parte a parte, ¿vale?
Importamos el módulo.
Creamos un servidor y para eso llamamos al método createServer que recibe un callback.
Ya explicamos lo que son los callbacks, ¿vale?
Los callbacks son funciones que se ejecutan después de que pase algo.
Normalmente cuando son cosas asíncronas, en este caso, una vez que recibe una request,
cada vez que recibe una petición, se ejecutará esta función de aquí.
Entonces dentro teníamos un console.log, request.receive,
y le decíamos la respuesta la terminamos enviando hola mundo.
Con esto teníamos el servidor y luego lo que hacíamos era escuchar en el servidor en un puerto.
Y finalmente este callback que teníamos aquí es cuando ya se haya levantado ese servidor en ese puerto
para tener la información en consola.
Para ejecutar esto, pues nada, vamos a node y ponemos punto barra clase2 barra 1.http.js, ¿vale?
Que es el nombre del fichero que tenemos aquí.
Si no, lo que podríamos hacer es entrar directamente en la carpeta y ejecutarlo, ¿eh?
Lo que queráis.
En este caso lo voy a hacer así y ya está, ¿vale?
¿Qué se me queja?
Vale, puerto is not defined.
¿Por qué me ha pasado esto?
Me ha pasado por diferentes motivos.
Lo primero, que no tengo el linter configurado porque lo he movido a una carpeta.
Así que vamos a hacer una cosita.
Vamos a iniciar aquí un proyecto, ¿vale?
Con npm init.
Esto me crea aquí el package.json y así con este package.json ya puedo instalar aquí
npm install standard menos d porque es una dependencia de desarrollo,
por eso la menos d mayúscula.
Y ahora, pues nada, vamos a poner que esto es linkconfig, extendemos de standard.
Y ahora aquí, pues me va a chivar donde tenemos errores, ¿ves?
Ahora me dice, eh, aquí tienes un error porque has puesto puerto y no está definido.
Efectivamente, porque es desire port, ¿vale?
Ahora lo tenemos mejor, así cometemos menos errores que se agradece.
Venga, vamos a ejecutar otra vez esto.
1.http.js.
Fíjate, me dice, servidor escuchando en el puerto, 1, 2, 3, 4.
Bueno, localhost, 1, 2, 3, 4.
Le podemos hacer clic y, aunque casi no se ve, ahí tenemos.
Hola mundo.
Lo interesante, lo vamos a tener realmente en la consola, ¿vale?
Para que no te vuele la cabeza, esto es muy importante que lo entiendas.
¿Por qué si solo he hecho una request, por qué me aparecen dos requests?
¿No?
O sea, ¿por qué?
Si yo le doy aquí a refrescar, en la consola me aparece repetido dos veces.
¿Sabes?
Parece que está recibiendo dos requests.
Muy bien, ya la gente del chat estaba ahí atenta.
El tema es que lo que está haciendo automáticamente el navegador es que cuando tú entras a una página web,
automáticamente hace dos requests.
Bueno, hace más requests, ¿vale?
Pero estas que ves aquí son de extensiones.
Estas las puedes ignorar.
Pero estas dos sí que las está haciendo.
Y esto es porque estamos haciendo una petición desde el navegador.
¿Qué es lo que está haciendo?
La petición que le hemos dicho y después está intentando sacar el favicon que lo tenemos aquí.
Lo más interesante y para empezar ya a crear nuestra API y entender cómo funciona esto,
tendríamos que ver qué es lo que tiene la request.
En la request podríamos ver que en el console.log ponemos rig.url.
O lo podríamos poner incluso aquí.
Espera, vamos a poner rig.url, ¿vale?
Y es la forma en la que vamos a poder empezar a traernos información de la request y discriminar nuestra API.
Discriminar quiere decir que nuestra API, dependiendo de los headers, dependiendo de qué ruta es y todo esto,
tendrá que responder de formas distintas.
Así que ahora, fíjate que esto no se está reiniciando solo.
Eso lo vamos a arreglar en la clase de hoy para que sepas cómo hacerlo.
Así que hay que cerrarlo con control C y volver a abrirlo, ¿vale?
Para que vuelva a tomar los cambios.
Y ahora si refrescamos, ahora sí en la consola, ¿ves?
Vamos a ver que ha recibido una request pidiendo por la barra y ha recibido una request pidiendo por barra favicon.ico.
Fíjate en una cosa, si yo voy aquí a la terminal, mira, por ejemplo, voy aquí a la terminal y aquí hago un curl http localhost 1.2.3.4, ¿vale?
Fíjate que aquí me está devolviendo el hola mundo y si miro en la consola, ahora solo ha hecho una request porque obviamente la terminal o si hago un fetch de una API,
no va a pedir el favicon porque no lo necesita, ¿vale?
Esa petición especial la está haciendo el navegador porque es más chulo que un 8, ¿vale?
Porque te está diciendo, no, no, pues me voy a traer el favicon que lo quiero.
Ahora que ya tenemos esto, te voy a explicar cómo funciona el tema de las requests y las responses.
Cuando hablamos de HTTP, te voy a comentar una cosa.
¿Qué es HTTP?
Que parece HTTP, HTTP.
Vamos a crear un servidor HTTP.
De hecho, ya lo tenemos creado porque si te fijas, hemos utilizado la dependencia de HTTP, ¿ves?
Del protocolo HTTP.
Entonces, ¿qué es esto de HTTP?
Es importante que entiendas lo que es porque justo cambia bastante y más adelante veremos que hay otros protocolos
que te pueden ayudar para comunicar otro tipo de cosas.
Pero HTTP es el protocolo de transferencia de hipertexto que se llama Hypertext Transfer Protocol.
Y es el protocolo de red, yo diría, más utilizado en Internet o de los más utilizados en Internet para transmitir información.
Especialmente páginas web, ¿vale?
Te voy a hacer aquí un dibujito para que entiendas cómo funciona, ¿vale?
No es la forma más avanzada y detallada, pero te voy a explicar porque es muy sencillo,
pero es súper importante que entiendas cada una de las partes.
Mira, vamos a poner aquí al usuario.
Vamos a llamarle user, pero podría ser Pepe, ¿vale?
Y Pepe tiene un dispositivo.
Mira, tiene un móvil.
Por ejemplo, tiene un móvil, ¿vale?
Entonces, Pepe, en este caso, vamos a llamarle Midu, Midu, Midu, nuestro usuario Midu, tiene su iPhone y dice,
bueno, pues vamos a hacer una petición a algún sitio, ¿no?
La petición es la request, la request, que en español, ¿no?
Le llamaríamos petición.
Y en la petición le enviamos cierta información.
¿Dónde la hacemos?
O sea, cuando yo estoy entrando aquí, fíjate, yo entro aquí a esta URL y esto me responde hola mundo,
ya estamos haciendo la petición.
Para ver la petición que estamos haciendo, lo mejor es que abras las herramientas de desarrollo,
te vas aquí, ¿ves?
Aquí, red.
Y aquí puedes ver la petición que estás haciendo.
Si refrescamos, ¿ves?
Aquí puedes ver las peticiones que ha hecho al entrar a esta página web.
Ya te digo que estas dos, que aparecen por aquí raras, muchas veces es porque hay extensiones.
Si no quieres ver las extensiones, puedes intentar abrirlo en modo incógnito o tener otro perfil aparte, ¿vale?
Pero en este caso, vamos a ignorar estas dos.
Tenemos la del favicon, que ya te he explicado, y la del localhost.
Esta del localhost, la que estamos haciendo la petición principal al entrar en esta URL, ¿no?
Aquí tendríamos información, por ejemplo, al hacer la request, tenemos a qué URL le estamos haciendo la petición,
cuál es el método de la petición, ¿no?
Como le estamos pidiendo, le estamos diciendo qué es un get.
Y aquí tendríamos más ya aparte de la respuesta, ¿vale?
Pero vamos a ver más cositas de la petición.
Fíjate que pone aquí, encabezados de respuesta y encabezados de solicitud.
Por ahora nos vamos a olvidar de la respuesta y nos vamos a enfocar en la solicitud.
Todo lo que veis aquí, todo esto en realidad es opcional, todo lo que veis aquí encabezado de solicitud es opcional.
Y a eso se le llaman headers, son las cabeceras.
Las cabeceras normalmente es información que va pegada a la petición como para darle más contexto a la petición, ¿vale?
Entonces, ¿qué información tendríamos en todo esto?
Pues fíjate, cuando hacemos una request, vamos a tener la URL, vamos a tener headers, vamos a tener el method, ¿vale?
El method, por ejemplo, el method puede ser el get.
Por ahora, yo creo que con esto podríamos tener suficiente, ¿vale?
Luego pondremos más.
Pero por ahora, esto sería lo más importante.
La URL a la que estamos haciendo la petición, los headers, las cabeceras,
donde le estamos dando como información extra de la petición.
Y fíjate, ahí puede haber, y lo veremos más adelante, puede haber tokens,
qué tipo de datos estamos esperando.
Le podemos enviar las cookies, ¿no?
Le enviamos como un montón de cookies para indicarle,
oye, esta petición es de un usuario que ha iniciado sesión.
Entonces, en los headers le pegamos las cookies.
Y en el método, lo que le estaríamos diciendo también es qué tipo de petición es.
Hay diferentes, luego los veremos, pero por ahora quédate que hacemos el get.
Y hay otra cosa que también es opcional, que dependiendo de lo que estemos haciendo,
también va con la petición, que es el body, es el cuerpo de la petición,
donde van todos los datos que queremos transmitir.
¿Dónde tiene que llevar esto?
Esto, obviamente, llega a nuestro querido servidor,
que esto es lo que vamos a hacer hoy, ¿vale?
Este es el server o el servidor.
Y entonces, cuando le llega la petición, ¿qué es lo que hace el servidor?
Pues el servidor, realmente, a sí mismo, ¿vale?
Está aquí un buen ratito, pues, haciendo cositas.
Vamos a mover esto, hacemos esto por aquí, vamos a mover esto por aquí,
y vamos a ponerle aquí, que por ejemplo, el recycle, ¿vale?
Procesar, ¿vale?
Está procesando.
Lo que hace es procesar toda la información,
y ya sea que tiene que ir a una base de datos,
que tiene que tratar la información, esto lo vamos a ver hoy.
Lo que hace es procesar estos datos, esta petición,
y una vez que tiene, y tarda lo que tenga que tardar,
pues una vez que tiene esto,
lo que hace es devolver una respuesta.
Sé que esto parece, alguien dirá, bueno, es muy fácil, ¿no?
Esto es muy fácil.
Puede ser que sea fácil, pero las palabras son clave.
¿Por qué?
Porque es imprescindible que entendáis las diferencias de la información que viajan entre la petición y la respuesta,
y qué es lo que cada una de las partes es lo que tiene que enviar,
porque ahora lo veréis que es en código, que es clarísimo.
¿Qué es lo que trae la respuesta?
El status code, ¿vale?
El código si ha ido bien, si es un 200, un 300, también lo vamos a ver ahora.
También podríamos tener el body, obviamente, el cuerpo de la respuesta.
Unos headers, ¿vale?
También podríamos tener unos headers.
También tiene cabeceras de respuesta.
Y esto sería como lo más importante.
El status code, como, oye, ha ido bien, ha ido mal, ha ido regular.
Las cabeceras de la respuesta.
Y ahí finalmente también el cuerpo, ¿vale?
Así que esta es la clave de cómo funciona el protocolo HTTP.
Hacemos una request donde le enviamos toda esta información,
y después la respuesta tendríamos status code, headers y body, ¿vale?
Y esta información es separada.
O sea, tendríamos, en realidad, el status code va en la cabecera,
pero vais a ver por qué es importante que va totalmente separada,
sobre todo cuando estamos tratando sobre esto.
Porque cuando se escribe la cabecera, cuando escribimos la cabecera,
primero le decimos status code y luego le decimos las cabeceras que puede tener, ¿vale?
Así que es importante que entiendas que va como de una forma separada,
y de hecho lo puedes ver aquí.
Fíjate que aquí, cuando tú haces una request,
fíjate que tenemos aquí, por un lado, los encabezados de respuesta, ¿vale?
Las cabeceras de respuesta y las de solicitud, ¿vale?
Pues fíjate que aquí no aparece el status code.
El status code, en cambio, sí que lo tenemos aquí.
Mira, teníamos el método y también estado, creo que es estado.
¿Ves? Estado. ¿Ves? 200.
Pero no aparece, cuando intentes buscarlo aquí, aquí no va a aparecer el status code.
Así que tienes el encabezado de respuesta, ¿qué te ha dicho?
La conexión, tipo de conexión, dejarla abierta.
Esto lo veremos más adelante.
La longitud de la respuesta, 10.
Esto quiere decir que han sido 10 bytes.
Y de hecho, si cuentas esta letra, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
¡Ojo!
10. ¿Por qué 10?
Porque 10 justamente son los bytes que vemos aquí, en el content length.
Fíjate que esto es información que ya estamos enviando desde el servidor.
¿Por qué es importante decirle la longitud?
Porque así el navegador sabe cuándo tiene que parar, ¿no?
Y dice, ostras, vale, la longitud es esta, entonces ya está correcto, ya terminamos y ya está, ¿vale?
Dice, sale arriba en general 200.
Sale aquí, pero en general, no es la cabecera de respuesta, ¿vale?
O sea, la tenéis aquí.
Aquí no aparece status code, ¿vale?
No se llama status code.
Se llama, o sea, el código de estado o el estado aquí lo tenéis como separado de las cabeceras.
Luego tendríamos el date, en qué fecha está hecho, y el keepalive, de cuánto tiempo tiene que estar abierta esa conexión.
Eso lo veremos más adelante porque es bastante interesante a la hora de optimizar recursos.
Luego tendríamos aquí los encabezados de al hacer la request.
Aquí hay cabeceras que por un lado vienen por el navegador, ¿vale?
Por ejemplo, ¿veis esta de access language?
Esto lo que está diciendo el navegador es que cuando hacemos la petición,
le estamos diciendo que nuestro navegador está en español, ¿ves?
En español de España y en español en general.
Y lo que estamos haciendo en este caso es que ya le está dando como una pista al servidor.
Que esto, si quiere, lo puede utilizar o lo puede ignorar.
Pero esto es clave porque hay muchas veces que podremos hacer, pues, peticiones a una API
y que la API, gracias a estas cabeceras, respondan de forma totalmente distinta.
Lo cual es súper útil, ¿vale?
Hay un montón de cabeceras que tienen más información, pero ahora mismo no es interesante.
La más importante, para que la tengas en cuenta y porque esta no importa si es el navegador o no,
que es esta de aquí, user agent.
Esta es una cabecera que se suele poner cuando se hacen peticiones como para decir quién eres tú.
¿Sabes? Como el agente de usuario.
Como decir, oye, yo soy el navegador de Chrome, no sé qué, tal versión de este sistema operativo,
no sé qué, no sé cuánto.
Y esto muchas veces lo que te ayuda es como en el servidor tratar este dato y decir,
bueno, si es un móvil voy a enviarle menos información o para temas de analíticas o para un montón de cosas.
Esto normalmente se utiliza no solo para esto, sino también para asegurarse de que ese usuario,
cuando vemos en las estadísticas, pero no para hacer tracking, sino estadísticas de servidor,
porque no hace falta muchas veces que sea un navegador el que hace la petición.
Puede ser un servicio, otra API, puede ser una terminal, puede ser un montón de cosas.
Y así puedes ver qué clientes son los que están utilizando tu servicio, ¿vale?
Son un montón de cosas.
Ya tenemos aquí en el Scalidrow, tendríamos la petición y tendríamos la respuesta, ¿no?
La petición, una vez establecemos la conexión, el navegador envía una solicitud HTTP.
Esta solicitud tiene como un formato estándar, contiene la información con el método,
ya hemos visto que GET para solicitar datos, puede ser POST para enviar datos, hay otros, luego lo veremos.
La URL que estamos pidiendo, la versión HTTP, esto también es importante.
Algunas cabeceras que son opcionales, como hemos visto, ¿vale?
Va al servidor, lo procesa y después de procesarlo envía una respuesta HTTP de vuelta al navegador,
al dispositivo, a la terminal, al cliente, a quien sea.
Con el código del estado, ¿vale?
Si ha ido bien, si no ha ido mal, 200 sería un éxito, 404 un error de que no lo ha encontrado,
luego veremos todos los que hay, ¿vale?
La versión de HTTP, más headers y también los datos que ha pedido, obviamente, ¿no?
O sea que en el body tendríamos los datos que se supone que hemos pedido.
Y ya está, ahí lo tendríamos, cerraría la conexión normalmente,
a no ser que tengamos una cabecera que le diga que la tenga que mantener abierta.
Vamos a utilizar el protocolo HTTP, pero el protocolo HTTP, de forma histórica,
ha tenido problemas de seguridad y por eso existe el protocolo HTTPS.
El HTTPS se puede utilizar en el localhost, pero hay que hacer un montón de cosas más
y por eso nosotros no lo vamos a utilizar porque necesitas un certificado y tal.
Pero puede ser que más adelante en las clases veamos cómo hacer el localhost con HTTPS
para que sí que lo puedas probar, ¿vale?
Pero ahora me parece un poco exagerado y así nos enfocamos en el HTTP con las APIs y tal.
Y luego muchas veces lo que pasa es que tú puedes tener un servicio HTTP en localhost
que funcione correctamente y cuando lo desplegáis lo que hacéis es que lo envolvéis
en un servicio que sí que es HTTPS.
De forma que internamente es HTTP, pero está envuelto en un protocolo HTTPS
y por lo tanto está todo encriptado y no tiene ningún tipo de problema.
Ya no lo tenéis que hacer vosotros y nos liáis.
Ya que sabemos todo esto, ya sabemos la teórica, ¿vale?
Vamos a mover las manitas que es lo importante.
Ahora que ya sabemos esto, vamos a hacer unas cuantas cosas.
Lo primero, ya sabemos que aquí es cada vez que recibe una request, una petición, vamos a tener esto.
O sea, cada vez que hace el usuario esto, veis esta request, esta request le llega al servidor.
Y este procesar sería justamente esta función de aquí.
De hecho, para que lo vean más claro, vamos a llamar process request, ¿vale?
Lo vamos como a separar y así lo vas a ver clarísimo porque no hace falta que sea una función anónima.
La puedes pasar así.
Ya sabes que las funciones en JavaScript son de primera clase y por lo tanto se pueden pasar como parámetro.
Así que esta función la creamos aquí y se la podemos pasar como un parámetro aquí.
Es exactamente lo mismo que hemos hecho antes.
O sea, esto que tenemos aquí es como esto, solo que lo estamos haciendo de forma separada.
Entonces, tenemos que procesar las requests.
Lo primero que queríamos hacer en cualquier API, en cualquier sitio, es el hecho de poder separar cada URL.
O sea, tú cuando vas a una página web, tú lo que quieres, por ejemplo, la PokeAPI.
Vamos a la PokeAPI.
Cuando vas a la PokeAPI, fíjate que tú tienes diferentes URLs que te responden cosas distintas.
Así que lo primero que vamos a querer es discriminar las URLs.
Ya tenemos aquí una pista, ¿no?
Porque nos pone request URL.
Así que nada, fácil, fácil.
¿Qué podemos hacer?
Oye, si la URL es igual a esto, entonces vamos a hacer algo aquí.
Vamos a decirle que el status code de la respuesta, pues mira, es 200.
Esto significa que ha ido bien, que es ok.
Luego veremos unos cuantos más.
Le podemos poner una cabecera, por ejemplo, para decirle, oye, el tipo del contenido es texto plano,
es HTML, es un JSON, es una imagen.
Podemos hacer un montón, ¿vale?
Hay un montón de diferentes content types.
En nuestro caso, le podemos decir que es un texto plano, por ahora, ¿vale?
Que es un texto plano, que no queremos hacer absolutamente nada.
Luego te enseño una cosa porque es esto interesante, ¿vale?
Y aquí le podemos decir, pues, hola mundo, vamos a poner aquí, bienvenido a mi página de inicio.
Ahora nos vamos a encontrar con un problema muy común en Node.js.
Conforme tú vayas trabajando con Node.js, vayas haciendo cambios y vas a querer que de alguna forma esto se reinicie automáticamente.
¿Por qué?
Porque si no es un rollo.
Imagínate, yo acabo de hacer estos cambios y ahora quiero ver estos cambios, a ver cómo funciona.
Y resulta que tengo que cerrar esto, volver a levantarlo y entonces irme otra vez a la página y ver cómo funciona.
Mira, fíjate que aquí hay un tema interesante que pone página y sale mal.
Esto es un problema del chart set, que también lo podemos arreglar.
Entonces, ¿qué podemos hacer para arreglar esto?
Tienes dos opciones para solucionar la actualización de tu código y que se reinicie automáticamente.
La primera, que sería la más recomendada, sería utilizar watch, ¿vale?
El modo watch.
Node-watch, ¿vale?
Y ahora le dices, pues, cuál es el archivo que quieres levantar.
Igual que lo hemos hecho antes, pero ves que hemos puesto aquí el watch.
Así que le ponemos aquí, boom, watch.
Ahora mismo está en experimental, aunque creo que la versión 20 ya no lo pone en experimental.
Es totalmente nativo y funciona perfectamente.
Fíjate que ahora ponemos un 2, 3, 4, ¿vale?
Bienvenido a mi página de inicio.
Vamos a probar, a ver si puedo ponerle res, set, header.
A ver si le podemos poner aquí el chart set.
Chart set, QTF8.
A ver si esto funciona.
Guardo y fíjate que al guardar, esto que ha pasado es que se ha recargado automáticamente.
Y ahora si venimos aquí y refrescamos, ¿vale?
Bueno, veo que no se ha tragado.
Pensaba que a lo mejor se lo comería ahí con el chart set.
Pero ya veo que no.
Pero si el chart set ahí está, QTF8.
A ver si se lo quitamos.
Normalmente lo que se hace es poner un meta.
O sea, que sí que está haciendo el cambio, pero no veo que el chart set este le esté afectando.
Lo que podemos hacer, en todo caso, claro, aquí es que es el texto plano.
Bueno, si le pudiéramos HTML, no sé si el chart set, a ver.
No sé si era app set, chart set, ¿puede ser?
Yo creo que es app set, chart set.
¿Puede ser?
Don't use this header.
Ah, mira, los browsers omiten, omiten este header no sé qué, no sé cuánto.
Puede ser que a lo mejor solo necesiten directamente app set, chart set, no sé qué.
Si no, lo podemos pasar directamente con el meta y ya está, ¿eh?
O con el content type directamente, ¿no?
Si no así, aquí, se lo podemos pasar aquí y yo creo que aquí seguro que funciona ya, ¿eh?
Pues no, tampoco.
Espérate.
Que igual lo he escrito mal, ¿eh?
Bienvenido a mi página web de inicio.
A ver si es con punto y coma, me parece.
Sí.
Vale.
Bienvenido a mi página de inicio.
¿Veis?
O sea, le ponemos content type, le decimos el tipo y aquí le decimos cómo es la codificación
de los caracteres.
Por eso, por eso, el acento no funcionaba.
Pero fíjate cómo de importante ya son los headers.
Cómo una cosa que parece tan sencilla ya está afectando a cómo nuestra página web
funciona.
Si no le pusiéramos esto, bueno, le podemos poner plano, ¿eh?
También.
Y fíjate que también funcionaría.
Así lo vemos en modo oscuro.
Pero fíjate cómo ya cambia.
Si le ponemos plano, ¿cómo me está devolviendo directamente el texto?
Si le pongo que es HTML, entonces esto detecta que es un documento HTML y lo intenta renderizar
como tal.
Y fíjate la diferencia.
Es que si tú pones que esto es HTML y pones un H1, H1, ¿vale?
Y refrescamos.
Ahora lo ha puesto como un H1.
Si le decimos que es texto plano, pues ahora me lo está devolviendo como si fuese texto
plano.
Y cómo de importante es la codificación, porque si no, pues la codificación no la entiende.
Claro, esto, pensad que en Estados Unidos no tienen este problema porque la codificación,
pues normalmente a acentos le importa un pepino.
Por eso a veces te puedes llegar a encontrar estos problemas en algunas páginas web.
Pero es verdad que lo normal es que mundialmente con un UETF8,
vayas bastante bien de no tener problemas de cómo se renderizan la codificación de los
caracteres, ¿vale?
Esta será nuestra primera ruta, pero podríamos hacer más.
Por ejemplo, podríamos tener una ruta diferente, ¿vale?
Luego lo arreglaremos mejor, ¿vale?
Ahora vamos a hacerlo con else if, else if, solo para que veamos.
Podríamos tener aquí, pues, el contacto.
Podríamos cambiar otra vez status code, charset, no sé qué.
Y aquí decir, pues, contacto, ¿vale?
Y aquí ahora, pues, un else que si por lo que sea no ha encontrado ninguno,
pues hacemos un 404, que esto significa que no lo ha encontrado.
Y aquí terminamos y le decimos que 404, not found, ¿no?
Bueno, podemos hacer el set header.
Bueno, fíjate que el set header, que ya vemos que todos son iguales,
podríamos ponerlo aquí, ¿vale?
Que quitaríamos todos estos de aquí y no lo estaríamos repitiendo,
porque total, para todos es exactamente igual.
Así que ahora, si vamos aquí, ¿vale?
Vamos a cambiar que esto sea plano por HTML, para que todos sean HTML.
¿Vale? Bienvenido a mi página de inicio, luego vamos a contacto,
una página totalmente distinta, y ahora si intentamos entrar a cualquiera, 404.
En un momento ya hemos hecho un servidor web, un servidor web.
Y fíjate, porque esto es muy interesante.
Hay un error muy común que os suele ocurrir muchas veces, ¿vale?
Os suele ocurrir muchas, muchas, muchas veces.
Y es el hecho de que cuando tenéis SPAs, cuando tenéis Single Page Applications, ¿vale?
Pues lo que os pasa es que decís, ¿por qué cuando voy a barra contacto y refresco no me funciona, no?
¿Sabéis que os dice, no me funciona y me dice que no encuentra la página?
Eso suele ser por dos motivos.
El primero, porque no hay un servidor detrás como este, que en este sí que tenemos un servidor,
donde está detectando cada petición y le está diciendo, vale, si va a barra contacto,
lo voy a detectar y voy a decir que renderice esto.
Pero pensad que cuando hacéis Single Page Applications, muchas veces solo renderizado en el cliente,
no tenéis un servidor detrás.
Y por lo tanto, lo que tenéis que hacer es siempre servir el mismo fichero independientemente de la ruta.
Porque no hay un servidor que sepa decir, ah, como es esta petición, tengo que renderizar esto, esta petición tal.
Y este error os lo he visto así de problemas, así de veces, así de veces.
Entonces, ahí lo que tenéis que hacer, como no sabéis responder a las rutas,
porque no hay un servidor que diga lo que tiene que renderizar cada cosa,
lo que significa es que tenéis que hacer, y normalmente esto depende del hosting y del sistema y tal,
que todas las rutas vayan siempre al índice, para que cargue el JavaScript y sea el JavaScript
el que hace el procesado de las rutas.
Vamos a hablar de los status code.
¿Veis que lo tenemos aquí?
¿Veis cómo lo ponemos de forma totalmente separada?
Obviamente, por defecto, ya podéis imaginaros que el status code 200 va a ser por defecto.
O sea, si vamos aquí al contacto y no le ponemos ningún status code, fijaos que por defecto es el 200.
El 200 significa que ok, ¿vale?
Pero hay un montón, de hecho los status code van desde el 100, vamos a hacer, te voy a hacer un croquis para que esto no se te olvide jamás.
Tenemos del 100 al 199, que diríamos que son respuestas informativas, ¿vale?
Lo vamos a poner este en blanquito.
Del 200 al 299, que son respuestas satisfactorias, ¿vale?
Satisfactorias no porque te haya hecho una satisfacción, sino porque ha ido bien la cosa, ¿vale?
Luego tendríamos del 300 al 399, que son redirecciones, ¿vale?
Y luego tendríamos los errores.
Los errores del 400 al 499, que son errores del cliente.
Porque normalmente estos errores quieren decir que tú desde la parte de la petición, o sea, del 400 al 409,
significa que tú, algo que has hecho aquí, al hacer la petición, es culpa tuya.
Podríamos decir, ¿qué quiere decir esto?
Puede ser que has intentado, intentar entrar a una página que no existe, estás intentando enviar datos que no se aceptan,
no tienes permisos para acceder a algo, ¿vale?
O sea, que son errores como de tu parte.
Y luego tendríamos los errores del servidor, del 500 al 599, errores del servidor, ¿vale?
Así que aquí tendríamos como las dos diferentes.
Las respuestas informativas, estos serían todos los status code, ¿vale?
Tendríamos todos estos status code que podéis utilizar como os dé la gana.
Obviamente no hace falta que os acordéis de todos de memoria.
De hecho, http.cat, aquí tenéis todos los status code explicados.
Bueno, explicados tampoco... Ah, sí, están explicados, es verdad, están explicados.
Ilustrados, que es lo más importante, ¿vale?
Por ejemplo, el 100 dice, continúa, switching protocols, procesando, early hands.
Este es muy interesante, por cierto.
Fijaos que aunque he dicho que es del 100... ¿Por qué os he dicho del 100 al 199?
Porque esto no para de evolucionar, ¿vale?
O sea, yo ahora os puedo decir, del 100 al 103, ¿no?
Porque ahora mismo solo hay tres status code que están en la especificación que quieren decir algo.
Pero puede ser que el 104, por lo que sea, lo creen por X motivo.
De hecho, para que te hagas una idea, el 103 es bastante nuevo.
¿Ves que pone que es una tecnología experimental?
De hecho, este es súper interesante.
Porque el 103 lo que permite es que puedas decirle, como darle pistas al navegador de qué recursos vas a necesitar.
Entonces, cuando el cliente hace una petición al servidor, imagínate que esa petición tiene que ir a una base de datos y tarda mucho.
Por lo que puede hacer el servidor, mientras está haciendo la petición a la base de datos, es darle unos early hints,
donde le va diciendo, oye, te voy a dar una pista al navegador, te voy a dar una pequeña respuesta en la que te va a decir,
ve cargando estos recursos mientras yo voy haciendo cosas, ¿sabes?
O sea, que está bastante interesante.
Voy a poner como los más típicos ever.
Tendríamos los más típicos, obviamente tendríamos el 200, que es ok, ¿vale?
Este no hay ningún tipo de duda, que es de los más importantes.
Tendríamos también redirecciones, el 301, que sería redirect, ¿vale?
De hecho, lo podemos ver al Michi, ¿vale?
Ah, movido permanentemente, importante, es verdad.
Es verdad, porque no es una redirección, redirección son todos.
Esto significa permanently, ¿vale?
301. Esto significa que el recurso, el recurso que había en esa dirección se ha movido a otro sitio, ¿vale?
Y entonces le redirigimos. 400, que es bad request, si no me equivoco.
400, bad request, ¿vale?
Esto significa que la request que has hecho no es correcta.
Puede ser que has pasado mal la URL.
Más bien que la información que estás enviando, la request está mal formada, ¿eh?
O sea, puede ser que la sintaxis de la request no esté correctamente, la query params, cosas así.
Así que vamos a ver ScallyDraw.
Esta sería bad request.
El más famoso, el más famoso, obviamente, el 404, not found.
Uno que no ha encontrado, o sea, has intentado acceder a uno que no existe.
Y el 500, internal server error.
Y este es uno de los más temidos, ¿vale?
Mira al Michi que está ahí dentro intentando arreglar las cajitas.
Este es uno de los más temidos, porque normalmente un error 500 es un error interno del servidor
que no tienes ni puñetera idea de qué es lo que ha pasado.
Así que estos son los más peligrosos porque, claro, seguro que os lo habéis encontrado alguna vez
de, oye, ¿qué ha pasado aquí? ¿Qué ha petado? ¿Qué no sé qué?
Bueno, pues estos serían como los más famosos, ¿vale?
A mí me gusta mucho http.cat porque, obviamente, es muy visual y se ve súper bonito.
Si queréis una mejor explicación como más técnica, os recomiendo esta, la de MDN,
que además de cada uno, pues tenéis un montón de explicaciones, se ve bastante rápido,
no tenéis imágenes que os vayan a estar como distrayendo y ya está.
Ya sabemos cómo podemos resetear el proceso.
Te voy a contar otra forma de cómo resetear el proceso, ¿vale?
La que os he enseñado esta está muy bien, ¿ves?
Que cuando guardo, pum, se resetea y podemos ver los cambios, ¿ves?
Mi página, perfecto.
Pero resulta que el modo watch este que estamos utilizando,
aunque funciona súper bien y te lo recomiendo un montón,
está todavía en experimental.
¿Ves que te lo pone aquí?
Bueno, está en experimental.
Yo, la verdad, es que siempre que lo he intentado utilizar ha funcionado perfectamente,
pero te voy a recomendar una opción alternativa por si, por lo que sea,
tenéis algún problema.
Existe una dependencia muy famosa que se llama Nodemon.
Nodemon, justamente esta herramienta lo que hace es detectar cuando hay un cambio en los ficheros,
es muy configurable, que eso es lo mejor que tiene,
porque no solo puedes escuchar los cambios del fichero de JavaScript,
sino que también lo puedes hacer de incluso otros ficheros, de un JSON, de lo que sea.
Lo malo, que funciona un poquito más lento, que consume más memoria,
tiene algunas, pues, cositas que hace que funcione un poquito peor.
Pero es mucho más potente, obviamente,
y tienes un montón de configuraciones que te puede ayudar.
Una de las malas prácticas que mucha gente aquí suele decir
es el hecho de que lo instales de forma global.
Mucha gente te dice, npm install menos genodemon,
haz esto y ya lo puedes utilizar en todos los sitios.
Mal, ¿vale? Mal.
Funcionar funcionaría, no pasa nada que lo hagas así,
pero lo cierto es que tampoco es necesario.
Pues si tenemos aquí en clase 2, vamos a poner el...
Vamos a inicializar aquí el package JSON, ¿no?
Lo que podéis hacer simplemente es instalar nodemon
como si fuese una dependencia de desarrollo con menos d, ¿vale?
No hace falta hacerlo de forma global.
Al hacerlo de forma global,
significa que una persona que, por lo que sea,
se está instalando este proyecto en clase 2,
no va a saber que necesita nodemon.
Es un poco raro.
Y además no vais a tener la posibilidad
de tener más de una versión de nodemon.
Lo más fácil es ponerlo como dependencia,
que la tenéis aquí,
y lo que debéis es utilizar scripts,
que esto os va a dar la vida.
Sinceramente, los scripts de npm
es una de las cosas más infravaloradas
que existen en el mundo de la programación web.
Solo a base de scripts podéis hacer lo que os dé la gana, ¿vale?
Entonces, lo que podéis hacer aquí,
poner dev,
y aquí hacéis nodemon con el script que queráis.
Y ya está.
Y una vez que hacéis esto,
ya hacéis npm run dev,
y además, lo más interesante de esto
es que crea una capa de abstracción
en el que ni siquiera tienes que saber
que estás instalando nodemon.
Simplemente tú entras al proyecto,
y haces un npm install,
y ya está esto como documentado.
Esto es mágico.
Porque tú puedes entrar a un proyecto,
haces un npm run,
ves aquí todos los scripts que tienes disponibles,
y haces npm run dev.
Y directamente esto ya te está ejecutando nodemon,
y te está funcionando perfectamente.
Mi opinión más sincera
es que evitéis hacerlo de forma global.
Tiene otros problemas de hacerlo de forma global.
Es verdad que una cosa positiva,
entre comillas,
sería la que han comentado de
así lo instalas una vez,
aunque para eso tienes alternativas
como utilizar pnpm,
pero una cosa bastante negativa
de instalarlo una sola vez también,
es que cada vez que cambiéis de versión de Node,
vais a perder todos los paquetes
que habéis instalado de forma global,
y por lo tanto los vais a tener que reinstalar.
Os voy a hablar ahora de las cabeceras.
Fijaos que aquí hemos dicho esta cabecera,
el text, html.
Podríamos hacer otra,
solo para que veamos rápidamente la diferencia,
y para que veáis
cómo podríamos servir archivos estáticos,
en un servidor web.
Y ahora luego haremos la API.
Vamos a poner aquí otro el shift,
vamos a poner esto por aquí,
para que veáis otra cabecera
que es interesante
y veáis cómo se hace
y cómo se cargaría,
por ejemplo, una imagen.
Vamos a buscar una imagen,
dejadme que busque por aquí una imagen.
Mira esta, que es algo ahí contento.
Vamos a poner aquí en clase 2,
¿vale?
Mira, con esta imagen, contento,
con la placa.
Vamos a darle placa, ¿vale?
Pues una cosa que es súper importante,
si queremos, por ejemplo,
servir una imagen,
lo que tenemos que poner aquí
es decirle la request de a URL,
y decirle específicamente
que cuando alguien pida
la imagen
superbonita.png,
nosotros vamos a responder
con esta imagen.
Pues lo primero que necesitamos,
seguro,
es cambiarle las cabeceras, ¿no?
Así que ya le vamos a decir,
oye,
el content type
es una imagen
y es del tipo png.
Súper importante,
porque fijaos
que los servidores
no saben cómo tratar
la información,
no saben si tú quieres
devolver un JSON y tal,
eso lo pueden hacer
framework automáticamente,
pero nosotros aquí
son los que les tenemos que decir,
los que tenemos que tratar
de darle la información
para saber
qué es lo que tiene que devolver
y cómo lo tiene que codificar.
Ya lo hemos visto antes
con el HTML.
Ahora,
vamos a traernos
el file system,
¿vale?
de Node.js,
esta biblioteca,
para leer justamente
el fichero
este de placa.png.
Así que vamos a hacer
un read file,
aquí vamos a,
claro,
no vamos a leer
imagen súper bonita,
sino que vamos a leer
placa.png.
Y aquí,
una vez que tengamos
la imagen,
lo que podemos decirle es,
mira,
si hemos,
si hay cometido un error,
le vamos a decir
status code que sea 500,
alguna cosa mal ha ido,
vamos a hacer esto
con un error,
internal server error,
¿vale?
Mira,
por ejemplo,
que había puesto mal
la URL,
o sea,
que hubiera entrado ahí,
luego lo intentamos,
¿no?
A ver cómo pasa esto.
Si hay un error
leyendo la imagen,
¿vale?
Pues tenemos que tratarlo,
súper importante siempre,
tratar los errores.
Y si no,
lo que podemos hacer aquí
es decirle,
bueno,
status code que sea,
200,
el que es por defecto,
o sea,
no haría falta,
el header este,
lo vamos a mover aquí,
importante que solo ocurra aquí,
porque si hay un error
y le ponemos que el content type
es otro,
pues ya tendremos problemas.
De hecho,
fíjate que ahora,
no sé si en este caso
lo va a machacar,
creo que sí,
lo podemos probar,
pero claro,
fíjate que la response
por defecto
le ponemos set header
como HTML.
Veremos si esto funciona
o se queda como HTML.
Lo probamos a ver
qué es lo que pasa.
Y ahora simplemente
lo único que tenemos que hacer
es devolver la información
que hemos leído.
Fíjate que esto es una cosa
muy chula de Node.js
que muchas veces
lo que hace es canalizar
el stream de datos.
Así que en este read file
que aquí tenemos este data
que es un buffer de datos,
un buffer en Node.js
es una clase global
que la utilizan
para trabajar con datos binarios.
Claro,
si tú lees un archivo .txt,
una imagen
o lo que sea,
lo que está pasando
es que lee el archivo
pero no lo está leyendo
como tú esperas.
Lo que está leyendo
son los datos binarios.
Entonces,
lo guarda en un espacio
de la memoria física
y ahí,
en ese espacio reservado,
pues tiene esos datos
de forma temporal
para que puedas tratarlos.
En este caso,
imagínate esto,
estamos leyendo este fichero
que es una imagen
pero no sabe
que es una imagen.
Simplemente,
lo que está haciendo
es leer estos datos binarios,
los deja reservados
en un espacio
y digamos que ahí,
en ese espacio reservado,
es un buffer.
Aquí tendríamos estos datos,
el buffer,
pero como datos binarios.
O sea,
todavía no es una imagen
ni nada.
Lo que estamos haciendo
es decirle,
esos datos binarios
quiero que me lo envíes
a la respuesta
pero ojo,
esta respuesta
es una imagen PNG
y ahí es donde ocurre
la magia de la codificación
donde el navegador,
pese a que nosotros
le estamos enviando
los datos binarios
tal y como lo hemos leído,
como le estamos diciendo
que es una imagen,
entonces va a ser capaz
de hacerlo.
Pensad que los buffers
son útiles
trabajando con archivos,
imágenes,
para criptografía,
para cualquier cosa
que no sean cadenas
de texto,
números,
planos y cosas así
o Jasons,
normalmente son útiles
y son esenciales
a la hora de trabajar
con transmisiones de datos
por cómo se leen
datos de archivo
o para recibirlos
a través de la red.
Muy bien,
pues ahora que ya tenemos
la imagen superbonita.png,
vamos a ver si esto funciona,
nos vamos aquí
a nuestro localhost,
localhost1234,
barra,
imagen superbonita,
vale,
y ha petado,
vamos a ver que,
ah, ha petado,
pero porque,
no es que ha petado,
es que ni siquiera
hemos levantado esto,
en pirendep,
vale,
vamos a ver ahora,
vale,
obviamente la imagen
es muy grande,
entonces por eso aparece así,
pero fíjate,
ahora ha detectado
que es una imagen
y por eso
ha funcionado correctamente,
si nos vamos aquí,
vamos a poder ver
que tendríamos el content type
por ahí
y que está funcionando
correctamente,
content type,
imagen barra,
png,
así que así es como
estamos enviando
desde un servidor
las imágenes,
vamos a hablar
del tema
de los métodos
que tendríamos
y así también
arreglamos un poco esto,
vamos a ponerlo en otro,
vamos a poner aquí
routing.js,
porque esto está bien,
pero bueno,
alguien me dirá,
joder,
pero están montando aquí
una para tener
diferentes rutas
que es un poco rollo
y seguramente
tiene razón,
lo que vamos a hacer,
vamos a crear
nuestra primera API,
lo voy a hacer desde cero
para que lo revisemos
un poco,
vale,
node,
http,
y así esto lo tienes
que pillar ya
casi en automático,
para procesar
la request
tendríamos esto,
por ahora la vamos
a dejar vacío,
para crear el servidor
http,
create server
y aquí procesamos
la request
y ahora
server listen,
le voy a poner
un,
dos,
tres,
cuatro,
vale,
y aquí simplemente
el console.log
del 1,
2,
3,
4 y ya está,
así que lo importante
está en el process request,
para crear nuestra primera API
vamos a tener diferentes métodos,
porque hasta ahora
solo hemos visto
el método get,
el método get
es el que hace por defecto
una página web
cuando tú entras a la URL,
ves que pone aquí
método get,
pero no es todos los métodos
que existen,
de hecho,
si vamos a mdn,
vamos a tener que hay
pero un montón,
los más típicos
son get,
get,
post,
put,
delete,
y options,
y patch,
trace también existe,
pero se usa,
no es que sea imposible verlo
y el de connect también,
pero los más típicos,
sobre todo hablando de HTTP,
son los que hemos visto,
¿no?
el get,
bueno,
para hacer una petición
que lo que queremos
es recuperar datos,
el get,
lo que estamos,
es exactamente lo mismo
que el get,
lo que pasa es que el get
se utiliza como para pedirle
que si se puede hacer la petición
pero que no hace falta
que me des el body,
¿vale?
no me importa el cuerpo
de la petición,
o sea,
no quiero la respuesta del cuerpo,
no quiero los datos,
lo único que quiero ver
es la cabecera de respuesta,
ya está.
A veces se hace,
es como idéntico al get
y a veces se hace
como para hacer
como un previo paso
para ver si una persona,
un usuario tiene permiso,
por ejemplo,
por sus tokens,
cookies y cosas así,
¿vale?
Luego tendríamos el post,
que es como para crear
una entidad de un recurso,
luego tendríamos el put,
que sería para reemplazar
un recurso que ya existe,
luego tendríamos el delete,
que es para eliminar
uno de los recursos,
tendríamos el options,
que es el que te describe
los recursos que se pueden hacer
en ese path,
que el options,
muchas,
muchas veces,
es el problema
que tenéis con el course,
es lo que hace el navegador
para hacer una petición
a un endpoint
como para decirle,
oye,
quiero que me indiques
con esta URL
que quiero acceder,
cuáles son los modos
que tengo permitidos
de comunicación contigo
y qué pasa,
que el options
justamente
es el que le devuelve
las cabeceras de course
y le dice,
vale,
pues que sepas
que las comunicaciones
que podemos tener
están limitadas
porque course
dice que por este dominio
no está aceptado,
por ejemplo,
¿vale?
Normalmente el post
es como para crear
un recurso entero
y en cambio el put
sería como para actualizar
una parte,
pero es que hay gente
que al final
también utiliza el patch
para eso
y el put lo utiliza
para todo,
de hecho leí hace poco
un artículo bastante interesante
de por qué no utilizaban post
y solo utilizaban put
y me parecía bastante interesante,
hay un montón de historias,
pero bueno,
normalmente en general
lo aceptado
es que el post
es para crear,
el put
es para modificar
como para reemplazar
casi todo,
o sea,
para reemplazar
todo el recurso
y el patch
sería para modificar
parcialmente
una parte de ese recurso.
Luego te puedes encontrar
que hay gente
que no utiliza el patch
para nada
y cosas así.
Ahora que ya sabemos
los métodos,
lo que podemos hacer
es de cada request
vamos a sacar
el method
y el URL,
¿vale?
Y vamos a hacer
un switch,
sí, señores,
vamos a hacer un switch,
un switch
donde vamos a tener
el case del get
y aquí podríamos tener
otro switch,
no soy muy fan de esto
y luego lo arreglaremos,
donde tendríamos,
oye,
si vas al caso este
entonces vamos a tener
que sea HTML
y esta es la página principal
y entonces,
bueno,
podríamos hacer un break
o podemos hacer un return aquí,
no vamos a hacer
la imagen súper bonita,
vamos a tener
un barra about,
¿vale?
para que empiece esto
a parecerse ya más
a una API.
De hecho,
vamos a hacer ya,
vamos a empezar ya
con la API.
Por ejemplo,
mira,
Pokémon barradito,
vale,
mira,
vamos a hacer aquí
Pokémon barradito,
¿vale?
Normalmente el Pokémon
barradito este
sería todo esto
que tenéis aquí,
bueno,
claro,
esto es mucha información,
pero bueno,
que la podéis tener igual,
de hecho,
vamos a poner aquí
Pokémon,
¿vale?
y vamos a poner aquí
dito.js.
¿Ves?
Aquí tenemos esta,
esto es un JSON
a saco,
lo que podemos hacer aquí
es const
dito,
¿vale?
JS,
ah,
espérate,
¿por qué no te gusta?
¿Qué es lo que se queja de?
No sé de qué,
const dito,
ah,
pero que nunca has estado
utilizado.
Es que fíjate
que es tan largo el JSON
que se vuelve loco,
¿eh?
Vamos a utilizar aquí
un módulo.export,
módulo.export
y vamos a poner dito.
Entonces ya tenemos
la información del dito.
Lo interesante,
esto está muy chulo
y es importante que lo sepas.
En CommonJS,
que serían los módulos
clásicos de Node,
puedes importar el JSON
automáticamente,
puedes importar JSON
automáticamente.
Entonces,
en lugar de hacer un JavaScript
aquí,
podríamos hacer un JSON,
¿vale?
Vamos a cambiarlo,
le pegamos todo esto,
esto sí que lo acepta
porque esto es un JSON
y puedes importar un JSON
aquí a saco,
¿vale?
Pokémon
barra dito.json
y esto se lo come,
¿vale?
dito.json,
ahora,
el header
le podremos poner aquí
application
barra json,
¿vale?
y a la hora de responder,
importante,
no vamos a devolver
el JSON automáticamente,
lo que tenemos que hacer
es transformarlo antes
en un string.
Lo que tenemos que devolver
es el string
y esto,
lo mismo,
lo podríamos hacer con otro.
No vamos a hacer todos los casos,
pero vamos a empezar ahora
ya con uno, ¿no?
Podríamos decirle
que el default,
aquí vamos a poner
que es un 404,
obviamente.
Podemos ponerle
que sea un HTML,
¿vale?
content type
con el
HTML,
charset,
¿vale?
Y ya tendríamos
el get.
Esto lo cerramos aquí,
este lo cerramos aquí
y podríamos tener también
el case aquí
del post.
Entonces,
ya podríamos ver
de cada request
el method
y tendríamos el post.
Y te voy a enseñar
una extensión
que para hacer
este tipo de cosas
te va a encantar,
¿eh?
Porque probar esto
en postman
y este tipo de cosas,
yo no soy muy fan
ya de postman,
de hecho,
me da bastante pereza
postman.
Es que se ha hecho
tan grande
que creo que hay
mejores alternativas
y hay un montón
de alternativas,
así que tienes
Thunder Client,
tienes Rapid API Client
y te voy a enseñar
una que para mí,
para esto,
creo que es la mejor
porque te ayuda
a entender
un montón de cosas.
Entonces,
podríamos tener aquí
case,
vamos a poner,
imagínate
que el mismo Pokémon
lo pudieras cambiar,
¿no?
Vamos a hacerlo
con el post,
o sea,
que pudieras crear
un Pokémon.
O sea,
vamos a poner
entonces que se pueda crear,
o sea,
Pokémon,
¿vale?
Así.
Y entonces,
en el case este
teníamos que leer
los datos,
¿vale?
Vamos a poner esto
porque este case
me está poniendo...
¡Ay!
Coño,
que he puesto ahí dos puntos
y los dos puntos
van después.
Aquí es donde vamos
a hacer...
Ahí está el truco,
¿vale?
Esto aquí
y esto,
¿sabes?
Vale.
Muy bien,
tenemos el get.
Vamos a probar primero
el get,
te voy a enseñar la extensión
y luego nos ponemos
con el post
y vamos a ver
cómo podemos recuperar
la información del post.
Entonces,
vamos a ver la extensión.
La extensión
se llama
REST Client.
Para mí,
la mejor en este caso,
¿vale?
Porque esta extensión
lo que vas a poder hacer
es tener aquí
un fichero
donde le vas a poder
como explicar
cada uno de los recursos.
Le vas a poder decir,
oye,
mira,
que haces un get
y entonces
aquí en esta URL
le puedes decir
el protocolo,
le puedes pasar
las cabeceras
y le puedes pasar
el body.
Hay otras,
¿vale?
Tienes,
por ejemplo,
que a mí me gusten,
Thunder Client,
que está muy chula también.
Thunder Client
es esta de aquí.
Muy chula,
aunque esta es como
más visual.
Ya verás que
REST Client
está bien,
¿ves?
Es más visual
como para que te guardes
todas las requests
y también otra
que a mí me gusta mucho,
Rapid Client.
Rapid API Client,
esta de aquí,
que esta la tengo instalada
pero la tengo ahora desactivada.
Esta además
lo que te puede hacer
es crearte
los tipos de TypeScript
y todo esto,
lo cual está súper chulo,
¿vale?
Que me gusta un montón
cómo se integra y tal
y la puedes sincronizar,
o sea,
puedes guardar
un poquito como Postman,
puedes guardar
todas las llamadas
en la nube
y todo puedes sincronizar
entre diferentes editores,
eso también está súper chulo.
Pero lo chulo
de la de REST Client
y por la que lo voy a utilizar
es muy sencilla
y para lo que queremos hacer
también,
pues creo que está perfecto
y así no nos tenemos que preocupar.
Ahora,
utiliza la que te dé la gana,
que yo sé que siempre,
no sé,
este tipo de
es que a mí me gusta
Thunder Client,
no sé qué,
y no sé qué os pasa
que es como un equipo de fútbol
que os ponéis,
a mí me encantan las tres,
normalmente voy cambiando
para no aburrirme,
pero si eres del equipo
Thunder Client,
oye,
utiliza Thunder Client,
si eres Rapid API,
pues la que te guste,
la que te dé la gana.
¿Qué es lo que tenemos que hacer
con la de REST Client?
Mira,
podemos crear aquí
un HTTP,
bueno,
o API request,
API.request,
¿vale?
No,
API.request no,
API.http,
perdón.
Y aquí lo que puedes hacer
es como decir
las peticiones que tienes
en tu API,
¿no?
Puedes decir get
y aquí vamos a hacer
HTTP,
localhost,
un 2, 3, 4
y en esta del routing
hemos dicho
barra Pokémon,
¿vale?
Nos lo vamos a copiar,
lo ponemos aquí.
Vale,
solo con esto,
que además está súper chulo
porque esto
ya lo dejas ahí,
lo puedes subir
al GitHub,
cualquier persona
se lo puede descargar
y entonces probar la API.
Solo con esto,
fíjate que aquí
me ha puesto este send request.
Bueno,
pues si le damos aquí,
pam,
vale,
me ha dado un 404.
O sea que algo que hemos hecho,
ah,
porque no hemos levantado,
vale,
no hemos levantado el tag.
Pero bueno,
está bien,
al menos ya sabemos
que nos ha dado un 404.
No he tenido que ir
al navegador,
cambiar del editor
al navegador y tal.
¿Qué pasa?
Que tenemos levantada
ahora mismo,
si miramos aquí
en el package.json,
¿ves?
Aquí estamos levantando el 1.
Podríamos poner
dev 1,
aquí dev 2
y que esto me levante
nodemon
y aquí sería
2.routine,
¿vale?
2.routine.js.
Y ahora vamos a hacer
npn run dev 2
¿Qué le ha pasado?
Vale,
hay algún problema
en mi código.
Lo voy a dejar funcionando
y miramos el código.
¿Qué es lo que le pasa?
Que algo no he cerrado,
¿no?
Este switch lo he cerrado,
este también lo he cerrado,
este switch también
y este también.
Vale,
es que hay uno de más,
¿vale?
Así que vamos a dejarlo por aquí.
Importante,
este,
mirad,
fijaos que sé que,
¿veis que este el inter?
Un expected lexical declaration
in case block.
Si estuviste en la depth leak
el otro día,
vimos justamente este error
porque este error
es muy,
muy interesante.
Y la constante,
si,
habría que ponerla
entre llaves.
¿Por qué?
Porque si no,
lo que está pasando
es que esta constante,
si tú tienes otro case aquí,
imagínate que tienes un break,
¿eh?
Aunque tengas un break,
tenemos aquí otro case,
otro,
otro,
¿vale?
Y aquí pongo const body,
aquí tenemos un problema
y el problema,
el problema que tenemos aquí
es que fíjate,
¿ves que me dice?
El identificador del body
ha sido otra vez declarado
y es porque las constantes
y el let,
lo que funcionan
es por el ámbito de bloque
y los bloques
se definen por las llaves.
¿Qué quiere decir?
Que en estas llaves,
dentro de este switch,
se está compartiendo,
estas dos constantes
están chocando
porque tienen el mismo nombre,
porque es a través
de las llaves.
Entonces,
habría que poner llaves
en el case,
que ya sabes
que son opcionales,
aunque son opcionales,
a mí me parece buena práctica
ponerlas normalmente.
Ahora se queja,
pero ahora se queja otra cosa
porque no lo estamos utilizando.
Ya veis que ahora
sí que está funcionando
perfectamente la API
que está abierta.
Vamos a nuestro API.http,
enviamos la request
y fíjate que ahora
ya tenemos nuestra primera API
con nuestro primer JSON,
con toda la información
que ha tardado 7 milisegundos,
tenemos toda la respuesta
con todas las cabeceras.
O sea,
está súper bien.
Vamos a hacer la del post,
que además la vamos a hacer
como al revés.
¿Por qué la vamos a hacer al revés?
Porque vamos a hacer primero
la petición.
¿Cómo vamos a hacer la petición?
Vamos a ver.
Vamos a hacer un post
y a ver,
aquí barra Pokémon.
Vale,
vamos a hacer un post
y ya vamos a hacer HTTP.
Bueno,
mira,
perfecto.
Ya me está pasando aquí
la información.
Aunque a mí me gustaría
que el content type
fuese lo que queremos enviar,
que sea una application JSON,
justamente.
O sea,
que les vamos a decir
una cabecera,
content type application JSON.
Vale,
para separar cada una
de las requests
tenéis que poner un comentario.
¿Vale?
Podéis poner aquí
tres cositas como esta
y podéis decidir aquí
para crear un Pokémon,
por ejemplo,
¿no?
Recuperar información
del Pokémon Ditto.
Lo bueno es que con esto,
fíjate que ya tenemos
la petición preparada aquí
para hacerla a nuestra API.
Aunque ahora mismo no existe,
¿eh?
Si la hacemos en request,
¿vale?
Pues,
bueno,
me está haciendo un waiting
porque esto se ha quedado ahí
en pajaritos
porque ha entrado aquí,
pero no está haciendo un rest
en,
no está haciendo nada,
ni siquiera tiene uno por defecto
para decirle un 404.
Así que el primero
que vamos a hacer
va a ser el 404,
¿vale?
Para que si no entra
en ninguno,
pues que al menos
le devuelva un 404.
Vamos a poner esto
y vamos a poner aquí
not found.
Vale,
404 not found.
Este lo quitamos
y vamos a arreglar
el caso este.
Este es un caso
muy interesante
donde además
aprendes callbacks,
cómo funcionan
los parseos
en OGS,
¿qué es lo que pasa?
Cuando nosotros
hacemos esta petición
le vamos a querer enviar
esta información
en el cuerpo del body.
O sea,
cuando nosotros
hemos visto aquí
que podíamos hacer
una request,
también hemos visto
que le podíamos enviar
un body
como un cuerpo
porque hay veces
que vamos a querer
crear algo en nuestra API.
Por lo tanto,
cuando creamos esto
le decimos,
oye,
esta es la información
que quiero enviar.
¿Cómo la recibe el servidor?
Bueno,
pues el servidor
la va a tener que leer
de la request
y en la request
¿qué es lo que tiene que hacer?
Pues escuchar
el evento data.
Conforme le va llegando data
va a decir,
vale,
voy a escuchando la data
que me va llegando
porque claro,
el body puede ser muy grande
y por lo tanto
como hay que pensar
como si fuese
una tubería,
¿no?
Una tubería
donde va pasando agua.
El agua
es la información
que estamos enviando
la petición.
Entonces,
lo que le estamos diciendo
es, bueno,
aquí vas teniendo
el cuerpo de la petición.
Pero claro,
piensa
que esto es una tubería
porque no es
o lo tienes todo
o no tienes nada,
sino que le va llegando
información.
Y aquí en Node.js
lo que le tenemos que decir
es, oye,
lo que tengo que hacer
es, vale,
mientras la request
está recibiendo
información
para cada trozo,
un chunk
sería como un trozo,
¿vale?
Por cada trozo
que voy a hacer
voy a estar
guardándolo
en una variable
que tengo aquí
que es esta de body
que vamos a poner
con su let,
¿vale?
Mientras vamos recibiendo,
mientras la request
está recibiendo datos,
voy a estar guardándolo aquí.
Pero claro,
¿este chunk
qué pasa?
Que este chunk
es un buffer.
Entonces,
porque va recibiendo binarios.
¿Qué es lo que queremos aquí?
Pues esto lo que vamos a hacer
es transformarlo
en un string.
Porque los datos
que estamos enviando aquí,
esto,
que mientras está enviándose
es un dato binario,
pero cuando lo estamos llegando
podemos transformar
un binario
a un string.
Y al transformarlo directamente
se va a codificar
exactamente correctamente.
¿Cómo pintaría esto?
Mira,
para que veamos un poco
cómo sería la cosa, ¿no?
Imagínate que queremos
enviar esto,
enviamos esto.
¿Qué es lo que va a hacer
los chunks?
Bueno,
pues primero o mejor
igual llega esto.
En el siguiente chunk
igual llega esto.
¿Vale?
¿Por qué?
Porque no siempre
no siempre llega
exactamente
la misma longitud,
¿no?
En la siguiente
pues a lo mejor
llega esto.
¿Vale?
Imagínate,
hasta aquí.
¿No?
Entonces aquí tendríamos
un chunk,
luego tendríamos este chunk,
luego tendríamos este chunk,
luego en el siguiente
pues tendríamos,
¿vale?
Un poco para que vayas
haciéndote a la idea,
¿no?
¿Vale?
Aquí más abajo
pues el transform
y aquí hasta aquí,
¿no?
O sea que tendríamos
aquí un chunk,
¿no?
Te lo voy a separar
con los comentarios estos,
¿vale?
Aquí teníamos chunk 1,
chunk 2,
¿vale?
Le va llegando así
porque es
la request,
como se hacen las peticiones
y eso lo puedes ver
fácilmente
y te lo puedes imaginar,
¿no?
Va siendo de forma progresiva,
entonces va entrando
por trocitos,
entonces en cada trocito
vamos haciendo esto
y ¿qué hacemos con todo esto?
Esto al final es un string
que lo estamos transformando aquí
y lo estamos guardando
justamente aquí.
Entonces aquí,
¿qué tendremos al final?
Pues lo que tendremos al final
es todos los chunks
que se habrán juntado
y tendremos
pues aquí
algo así,
¿vale?
Obviamente bien escapado
pero para que te hagas la idea,
¿vale?
Tendríamos algo así,
¿vale?
Lo habremos juntado todo,
eso cuando haya llegado
el último chunk.
¿Cómo sabemos que ha llegado
el último chunk?
O sea,
¿cuándo sabemos que ha terminado?
Pues como te dije,
Node.js está basado en eventos
y esto lo que quiere decir
es que
cuando tengamos el evento
de que ha terminado
nos lo va a decir
request on end,
vale,
pues ya hemos terminado.
Si ya ha terminado,
¿qué quiere decir?
Que vamos a tener la data
y vamos a poder parsear
todo lo que tenemos
en el body,
¿vale?
Porque ahí ya tenemos
toda la información.
Podríamos hacer diferentes cosas aquí,
podríamos llamar
a una base de datos
que esto lo haremos
en el curso,
una base de datos
para guardar la info,
¿vale?
Por ejemplo,
podríamos hacer lo que sea.
Para ver que todo
está funcionando correctamente
lo que vamos a hacer
es devolver los mismos datos
para ver, ¿no?
Así que vamos a escribir
y te voy a enseñar
otra forma
de cómo podemos
escribir la cabecera
que ya te he enseñado
la status code
y aquí poner
el set header,
pero también puedes escribir
directamente el header
mientras lo estás enviando.
Puedes hacer
res.writehead
y ya escribes
la cabecera
y le dices,
vale,
201 porque
201 hemos visto
que es cuando
has creado el recurso.
En este caso
se supone
que hemos llamado
a una base de datos
para guardar la info
y por lo tanto
hemos guardado el recurso
y le podríamos decir
pues eso,
que es una application JSON
con el chart set
o etf8
y podemos terminar aquí
diciendo,
oye,
vamos a hacer un JSON
stringify
de justamente
los datos,
¿vale?
De los datos
que hemos recibido.
Al menos deberíamos ver
que lo mismo
que ha llegado
es lo que debería devolver
y aquí
pues ya
podríamos hacer,
aquí vamos a hacer un break,
¿vale?
Para que no llegue al siguiente caso
y ya lo tendríamos.
Pues con esto tendríamos el post.
Si volvemos aquí
y le damos a send request,
¿vale?
Fíjate que ahora
sí que ha llegado.
O sea,
me está devolviendo
exactamente lo mismo.
Mira,
voy a modificar esto.
Vamos a poner aquí
un data,
timestamp
y vamos a poner date now
solo para que veas
que realmente
está haciendo algo,
¿vale?
Send request,
¿ves?
Timestamp,
tal.
Cuando se ha creado,
timestamp,
pues esto.
Aquí tendríamos
la información que se ha creado,
que ha recibido
y esto es el momento
en el que se ha creado
ese recurso.
Y con esto
ya hemos hecho
de forma totalmente nativa
una API
para get
y para post.
Entiendo que alguien
tiene que estar aquí,
joder,
pero es que yo no me voy
a poner a hacer estas cosas.
Bueno,
pero es importante
que lo entiendas
porque esto es lo que
como funciona por debajo
Express.
Ahora vamos a ver
Express,
¿vale?
Express es seguramente
si hay algo
que tienes que aprender
con Node.js
es Express.
Express es
el framework
más utilizado
más utilizado
y es un framework,
¿vale?
Que hay gente que
es una biblioteca,
es un lenguaje de programación,
es...
No,
es un framework
y no es mi opinión,
¿ok?
Es un framework
porque lo dicen aquí,
es un web framework
para Node.js.
Es un framework
que te permite
hacer aplicaciones web,
APIs,
que tienes...
Que se utiliza por debajo
en un montón
de otros frameworks
como por ejemplo
Next.js,
Nest,
un montón.
Webpack creo que utiliza Express.
Hay un montón,
un montón de herramientas
que utilizas en tu día a día
que utilizan Express.
Express parece mentira
pero es una biblioteca
que lleva 10.000 millones de años
funcionando en Node.js
que por desgracia
no se actualiza tanto
como nos gustaría
pero que al final
realmente
ha sido
muy confiable,
muy utilizado
y que sigue utilizándose
y no ha tenido ningún problema.
Vamos a ver
cómo utilizar Express
para recrear
lo que hemos hecho,
qué diferencias hay,
qué nos aporta Express
y cómo poco a poco
podemos mirar
lo que hemos aprendido,
el cómo funciona
y todo esto
pero a Express
y en qué nos ayuda
y cuál es su ventaja.
Dicho esto,
vamos con Express.
.express.js
Lo primero que tenemos que hacer
para utilizar Express
es instalar Express.
Así que nos vamos
a la carpeta
de la clase 2,
npm install,
Express
y en este caso importante,
Express es una dependencia
de producción
así que
modo exacto,
¿vale?
Para que no nos ponga el caret,
importante
y ahora en el package.json
ahí tenemos
nuestro querido Express.
vamos a poner aquí
un defress
y aquí
vamos a utilizar
nodewatch3.express.js
¿vale?
Muy bien,
vamos a cerrar esto
y vamos
a nuestro fichero de Express.
Lo primero que hacemos
con Express
vamos a importar
el framework
de Express
y una vez que tenemos
el framework
lo que hacemos es crear
la aplicación
con Express.
Ahora,
aquí en Express
aquí tenéis diferentes
opciones
que podéis pasarle
y tal,
por ahora no las vamos a ver
pero seguramente más adelante
el puerto
vamos a tener el puerto
vamos a utilizar el 1, 2, 3, 4
si no le ponemos
una variable en torno
pero luego
vamos a crear
nuestro propio .env
vamos a hacer aquí
un app get
y ¿qué es lo que hacemos aquí?
Lo que hacemos aquí
fíjate la diferencia
¿no?
Aquí lo que teníamos
es una función
que respondía
cada vez
a todas las requests
y era dentro
de la función
que teníamos que discriminar
según el método
según la ruta
¿no?
y tenemos que decirle
oye pues esto va aquí
esto va acá
aquí
lo que vamos a hacer
es hacerlo al revés
está basado más
en las rutas
lo que quiere decir
es que le decimos
la app
y luego le decimos
la acción
aquí le decimos
el método get
así que
en la aplicación
cada vez que reciba un get
en la ruta
barra
¿vale?
entonces quiero
que me respondas
y aquí sí que tendríamos
una función
que sería la que responde
cuando hace un get
en esta ruta
¿vale?
así que ya puedes ver
un poco la diferencia
en cómo sería aquí
de forma muy imperativa
el que tienes que
ver el método
la ruta y tal
hacerlo aquí
que lo que estamos haciendo
es directamente decirle
cuando la app
recibe un get
en esta ruta
entonces
ejecutas esta función
¿ok?
y ahora
tendríamos la respuesta
esta respuesta
que tenemos aquí
es un poquito
más especial
y más amplia
que la que tenemos
en Node.js
en Node.js
fíjate que tenemos
que poner el set header
el status code
lo podemos hacer así
status code
y decirle el número
lo que podemos hacer
en Express
tenemos una API
que lo que nos permite
y además es encadenable
podemos decirle
oye
aquí el status es 200
que ya te digo
que por defecto es 200
pero al menos
para que lo veas
¿vale?
y ahora
podemos enviar
y le decimos
mi página
¿vale?
esta sería nuestro
nuestro primer endpoint
que vamos a hacer
luego lo vamos a pasar
para tener el API
¿vale?
vamos a hacer una API
y no solo el HTML
por una parte
tendríamos esto
¿vale?
nuestra primera ruta
y ahora tenemos que
igual que hemos hecho antes
pues tenemos que levantar
y escuchar un puerto
o sea
en qué puerto
nuestra app
va a funcionar
le hemos dicho
que lo vamos a escuchar
de la variable de entorno
en un 2, 3, 4
por defecto
y aquí es exactamente
lo mismo
que teníamos
en el otro sitio
de hecho
esta parte de Express
es literalmente
literalmente
esto de aquí
literalmente
porque es la misma API
por debajo
¿vale?
así que si alguna vez
te preguntaba
de dónde salía esto
esto es
pues algo de Node
básicamente
está utilizando
la misma API
muy bien
entonces
ya tendríamos aquí
nuestra primera ruta
vamos a ver
si esto funciona
levantamos el 3
¿vale?
en un 2, 3, 4
vamos aquí
vale
diferencias importantes
¿vale?
ya tengo aquí mi página
perfecto
pero fíjate
que no le he puesto
el content type
y ha detectado automáticamente
que esto es un HTML
esta es una de las grandes diferencias
a la hora de utilizar Express
que Express automáticamente
va a detectar
muchas veces
cuál es el content type
correcto
que tiene que utilizar
dependiendo de la respuesta
que estáis utilizando
así que
te va a quitar un montón de código
y de hecho
aquí lo que vais a tener
es que este status 200
lo vamos a poder quitar
ya le podéis decir directamente
res.sent
¿no?
y aquí tendríamos la respuesta
como le hemos devuelto
directamente un HTML
ya por defecto
está poniendo
que sea HTML
pero claro
si aquí le dijésemos
oye pues
claro
no va a funcionar
exactamente así
porque
tendríamos otras formas
por ejemplo
de devolver un JSON
aquí tendríamos
para devolver un JSON
directamente
tendríamos un método
que es JSON
y así automáticamente
por dentro
lo que está haciendo
es decir
vale
pues ya pásame el JSON
que yo ya hago
el stringify
ya le cambio el content type
y todo
y entonces cuando entres
ves
ya me está devolviendo
un JSON
con todo correcto
estas son las grandes maravillas
que tienes en Express
que te facilita un montón esto
pero obviamente
aparte de esto
aparte de esta facilidad
también tiene
lo de las rutas
por ejemplo
antes habíamos visto
como habíamos hecho el post
vamos a migrar
el post este
que habíamos hecho
vale
lo vamos a migrar
entonces me lo voy a copiar
voy a copiármelo
un poco por aquí
y vamos a ver
queríamos hacer un app.post
vale
y era barra Pokémon
y aquí dentro
hacíamos todo esto
vamos a ver
vale
aquí dentro
me he copiado exactamente
lo que habíamos hecho antes
lo bueno
es que funciona
igual
o sea
esto funciona exactamente igual
no hay ningún problema
de que esto funcione
a ver
podríamos hacer algunos cambios
porque como te he dicho
esto del JSON
ya no hace falta
lo del write
podríamos ponerle
el 201
si quisiéramos
pero todo esto
lo podríamos simplificar
en lugar de necesitar
hacer todo esto
fíjate que
una cosa
JSON parse
esto sí que lo necesitamos todavía
pero
el write head
y todo esto
podríamos hacer
res.status
201
punto
JSON
y enviar el data
vale
ya podríamos quitar
todo esto
ya no necesitamos
escribir la cabecera
manualmente
pero todo lo demás
ahora mismo
sí que lo necesitamos
luego lo vamos a arreglar
porque vamos a utilizar
un concepto
muy interesante
que tiene Express
pero vamos a ver
si esto
funciona correctamente
si podemos crear todavía
nuestro
nuestro Pokémon
enviándole
la información
nos vamos aquí
send request
vale
y fíjate
que sigue funcionando
correctamente
aquí tenemos el status
code 201
y fíjate
que tenemos
una cabecera
nueva
entre todas las cabeceras
que tenemos en la respuesta
hay una nueva
que se llama
xPowered by Express
cuando utilizamos ciertos
frameworks
o tal
le añaden una cabecera
extra
como para
indicarle al mundo
que está utilizándose
esto también
a veces lo utilizan
incluso para temas
de estadísticas
en las que
por ejemplo
Wapalizer
lo puede mirar
para ver si estás
utilizando Express
Wapalizer
es una extensión
que te dice
que tecnologías
utilizan a página web
o también para un tema
de estadísticas
entonces
hay un montón
un montón de frameworks
que hacen este tipo
de cosas
ahora bien
yo os recomiendo
que lo quitéis
¿vale?
¿por qué?
porque resulta
que esto
es un problema
puede ser un problema
de seguridad
por suerte
por suerte
al menos
solo aparece
la tecnología
¿por qué?
porque si además
apareciese
en la versión
sería muy grave
imagínate
que tenéis la versión
4.11
¿ok?
y resulta
que 4.11
no la actualizáis nunca
y tiene un bug
crítico
un fallo de seguridad
y aparece ahí
esto es un problema
que muchas veces
a veces pasaba
en WordPress
y todo esto
lo digo para que lo sepáis
que a ver
en este caso
no pasa nada
mejor si lo dejáis
pero se puede desactivar
para eso
podéis ir aquí
y en la app
podéis hacer un
app.disable
¿vale?
xPowerBy
¿ves?
ponéis esta línea
de aquí
y ahora
si guardamos los cambios
y volvemos a enviar
la send request
¿vale?
ha desaparecido
lo digo porque
es bastante interesante
que este tipo
de cabeceras
si no os aporta
absolutamente nada
las quitéis
no es que sea
la gran cosa
pero os estáis evitando
unos pocos bytes
¿vale?
muy bien
esto funciona
exactamente igual
como teníamos antes
ya tenemos
bueno
podría hacer también
como teníamos
el get aquí
¿no?
este también
lo voy a hacer
¿vale?
para que quede exactamente igual
y así tenemos aquí
el pokemon get
vamos a pillar
el json
del dito
¿no?
que esto está en require
barra pokemon
barra dito json
os sorprendería
la de apis
que son así
con
o sea
importando
directamente
json
el dito
vale
pues aquí
podríamos hacer
res.json
devolviendo el dito
ya teníamos el get
y el post
o sea
que tendríamos exactamente
lo mismo que teníamos
teníamos en la otra
¿no?
excepto el 404
¿qué pasa con el 404?
¿cómo hacemos un 404
en express?
si miramos de arriba abajo
cómo está funcionando
nuestra aplicación
¿no?
estaríamos viendo
espera
voy a mover un poquito
estas cosas
estaríamos viendo
cómo funciona
la aplicación
va
si tienes un get
y vas a esta url
va a responder
si tienes un post
y vas a esta url
va a responder
pero ¿qué pasa?
si vas a localhost
1.2.3.4
y vas a esta url
vale
por defecto
te va a poner aquí
un cannot get
te va a dar un 404
not found
pero no estamos tratando
exactamente bien el error
para hacer esto
lo que tenemos que hacer
es utilizar
como
una forma global
de tratar
todas las requests
y lo interesante
es hacerlo
en
orden
tiene que ser
la última
o sea
tenemos que ponerlo
al final
porque va en orden
primero va a intentar
esta
luego va a intentar
esta
y finalmente
va a llegar a esta
si llega a esta
y no le ponemos
ningún tipo
de request
o sea
no le estamos poniendo
ningún path
ninguna url
ahí
y directamente aquí
ya le podemos decir
que esto es un 404
porque esta va a ser
la última
la última
a la que va a llegar
y va a responder
como ponemos un .use
aquí podríamos poner
.get
.post
.delete
podríamos utilizar cualquiera
pero al utilizar un .use
esto es como poner un asterisco
esto significa que para todas las acciones
sea get
post
options
lo que sea
va a pasar por aquí
ahora al guardar los cambios
si vamos aquí
fíjate
ahora tengo un 404
porque le he dicho que me devuelva un HTML
con el 404
¿vale?
así que esto ya lo tenemos
y fíjate
para comparar
como lo teníamos antes
y como tenemos ahora
tenemos con express
que son 35 líneas
y antes habíamos creado el servidor
con 56
un ejemplo
muy sencillo
fíjate que la diferencia son 56
o sea
son 20 líneas
más o menos
¿no?
pero vamos a por más
mucha de la magia que tenemos muchas veces con express
¿vale?
es el hecho de los middleware
¿qué es un middleware?
¿y por qué son importantes?
a ver
en express
te voy a contar
te voy a hacer un croquis
te voy a hacer un croquis
que sé que os gustan los croquis
imaginad
que tendríamos
esto sería
como la request
¿no?
que teníamos antes por aquí
tenemos aquí la request
tenemos la request
imaginad que esto sería
ya en express
tenemos esto
pa pa pa
esto es express
express
nuestro maravilloso express
por lo tanto la request
viene desde fuera
¿no?
viene desde fuera
y aquí
lo estaríamos tratando
la request
la tendría
entraría desde fuera
y lo estaríamos tratando
cuando entramos
imagínate que estamos entrando
en el app.get
pokemondito
¿vale?
este pokemondito
sería la url
url pokemondito
¿vale?
el method
es get
¿vale?
esta sería la request
que se está haciendo desde fuera
entra en express
y aquí nos encontramos
este código de aquí
¿no?
o sea que tenemos
este app.get
¿vale?
perfecto
y por lo tanto
vamos a ponerlo aquí
app.get
¿no?
y aquí
la función
y aquí
pues dice
vale
esta request
tiene que entrar aquí
esta request
dice
tiene que entrar aquí
¿vale?
aquí pues se procesa
hacemos el procesamiento
que haga falta
vamos a hacer aquí
el procesamiento
que haga falta
pam pam pam
lo movemos así
bueno esto no sé
por qué se ha movido
¿por qué te has movido
maldita?
es que hay una cosa
que me da bastante rabia
de Excalibur
que es que hay que darle
más de una vez
a ahora
¿vale?
y aquí tendríamos
el procesamiento
¿no?
eh
proceso
el proceso
justamente
es lo que tenemos
en esta fn
o sea aquí es donde
se estaría procesando
pero resulta
que en este caso
es porque tenemos
una sola
¿no?
o sea parece que tenemos
una sola
y por lo tanto
lo que pasa aquí
es que aquí tenemos
la request
¿no?
termina aquí
esto lo podemos hacer
ya más pequeño
de hecho lo podemos poner
hasta aquí
¿vale?
y aquí ya tendríamos
la respuesta
que habíamos hecho aquí
esta sería ya
la respuesta
y la respuesta ya
pues iría al usuario
¿vale?
tenemos la request
entra aquí y tal
si fuese un 404
pues esto iría para allá
vería que hay 404
no es de etc
y tal
pero aquí sí que lo he encontrado
¿qué pasa?
que este proceso
está muy bien
cuando justo tienes
una
cuando tienes una
pero
¿y si te digo
que tenemos una cosa
especial
en Express
por la que puedes hacer
que pasen
todas las requests
que tú quieras
antes de que llegue
exactamente
a la que trata
esto
aquí
se le llama
middleware
y los middleware
lo que hace
básicamente es
que las requests
las que tú quieras
también
pasan por ahí
procesan
o hacen cualquier cosa
¿vale?
pueden por ejemplo
extraer cookies
validar
si el usuario
está logueado
extraer la información
del JSON
cualquier tipo de lógica
¿vale?
es como algo previo
a tratar la request
y aquí luego
luego lo que hace
aquí
sería llamar
al método
next
para ir
a la siguiente
¿vale?
y dice
vale
cuando he terminado
ya de procesarla
en el middleware
lo que llamo
es al método
next
para que continúe
viajando
la petición
vamos a verlo
en ejemplo
con un código
el middleware
es una función
que se ejecuta
entre la petición
y la respuesta
así que
¿cómo tenemos que poner
el middleware?
obviamente
lo vamos a querer poner
antes
así que los podemos poner aquí
fíjate
como de sencillo
podría ser
de hecho aquí
podríamos poner
use
y tal
y podríamos poner
request
res
y hay un tercer parámetro
que se llama
next
¿por qué?
porque con next
lo que vamos a decirle
es que cuando terminemos
de hacer aquí
lo que queramos hacer
que aquí puedes hacer
mi primer
mi primer
middleware
y aquí podríamos
por ejemplo
hacer un tracking
podemos
trackear
la
request
a
la base de datos
revisar
si el usuario
tiene cookies
podrías hacer
lo que tú quieras
puedes hacer un middleware
que afecte
a todas las peticiones
o puedes
poner aquí
las peticiones
a las que quieras
que le afecte
¿vale?
tú aquí puedes poner
la url
que tú quieras
puede ser
por ejemplo
que solo
en todas las urls
que sean
que empiecen por Pokémon
que le afecte
o puede ser
que sea
simplemente
en la home
depende de lo que tú quieras
normalmente
muchas middleware
son para todo el mundo
también incluso
los middleware
podrías hacer
que sea
para una
para una acción
en concreto
solo para los get
solo para los post
todo este tipo de cosas
por ahora
vamos a hacer
el primer middleware
que sea así
pero ojo
muy importante
no se te puede olvidar
el next
y vas a ver por qué
porque si tú lo dejas así
y no hacemos nada más
y ponemos esto
lo que va a ocurrir
es que si tú intentas
entrar ahora
vamos a hacer la API aquí
y voy a hacer
el get
del Pokémon Ditto
y hago la request
¿vale?
y fíjate
que se me ha ejecutado aquí
mi primer middleware
tenemos aquí
pero no estoy recibiendo
la respuesta
está aquí
haciendo un waiting
porque no estoy recibiendo
la respuesta
porque no estoy contestando
se ha quedado aquí
no estoy enviando respuesta
y tampoco sabe
cómo seguir la petición
porque soy yo
quien tiene que decirle
que tiene que continuar
así que le tengo que decir
next
le tengo que indicar
que una vez que he terminado
de hacer lo que quiere hacer
tiene que continuar
a la siguiente ruta
que corresponda
entonces una vez que llega aquí
next
significa que va a intentar
de este next
va a intentar ir aquí
que en este caso
sí que entrará
porque la URL
sí que machea
o intentará con esta
y si no puede con ninguna
irá al 404
que hemos dejado aquí al final
lo vamos a ver ahora
como he puesto el next
ahora
si hago aquí este get
send request
¿ves?
ahora tenemos la respuesta
pero vemos que ha pasado
también por mi primer middleware
o sea que ha pasado
por el middleware
pero a la vez
también me ha contestado
y gracias a esta diferencia
de poner el next
ahora bien
¿para qué podemos utilizar
el middleware?
está muy bien
todos los ejemplos
que me has dado
pero no me has convencido
dame un ejemplo real
bueno
pues hay un ejemplo
muy chulo
que te va a gustar
y es que
fíjate
aquí tendríamos
por ejemplo
toda esta información
imagínate
¿un middleware
puede ir después de las rutas?
es muy buena pregunta
y la verdad es que sí
sí que puede
puede ir entre rutas
y puede ir al final
por ejemplo
esto no deja de ser un middleware
la última a la que va a llegar
esto no deja de ser un middleware
si lo ves
lo que pasa es que es un middleware
no es un middleware
en cuanto a concepto
porque el concepto de middleware
es como un
algo que se ejecuta en el medio
¿no?
y se supone que es en medio
entre la request
y la respuesta
como algo
como podrías intentar
entenderlo incluso como un proxy
es algo que intercepta
la petición de entrada
que la puede tratar
la puede transformar
para que luego la puedas
pues responder tranquilamente
¿no?
puedes utilizar el middleware
para ponerlo en medio
para lo que te dé la gana
es que
son un montón de posibilidades
entonces como concepto
esto no sería un middleware
pero en cuanto a sintaxis
sí que lo sería
¿vale?
así que sería un poco así
un middleware y un proxy
pueden ser bastante similares
en cuanto a que están interceptando
¿vale?
pero al final
la idea
de lo que hace un middleware
y un proxy
son distintas
porque un proxy
la idea sería más
de interceptar
requests
para cambiarlas
y moverlas
¿no?
y decir
bueno pues esto
lo intercepto
pero voy a hacer
que responda
con esto otro
un middleware
va un poco más allá
o sea
en el concepto
de tratar
la request
¿no?
o sea
más de
no solo interceptarla
sino que lo estamos llevando
un poquito más allá
es una función
que lo que estamos haciendo
es que haga una tarea
por eso se le llama
como middleware
porque lo que hace
es más de código
no tanto de tratar
de hacer una reacción
que también se podría hacer
pero son parecidos
pero no son exactamente
lo mismo
en cuanto a concepto
porque
el proxy
no sería tanto
de hacer algo
¿sabes?
de tener lógica
de validaciones
y tal
sino sería más
de orquestrar
eso podríamos
pensar un poquito
esto ¿no?
¿un middleware
podría rechazar
una request?
podría rechazar
vamos con esto
ahora que ya tenemos
lo del
middleware
¿vale?
si digo middleware
y es middleware
bueno
vamos a ver uno
que es que
os va a encantar
porque
mucha gente
no sabe
de dónde sale
esta magia
mira
aquí tenemos
carne de middleware
de middleware
perdón
mira
este de aquí
esto
lo podríamos extraer
y crear
nuestro primer middleware
que podemos reutilizar
en cualquier sitio
que nos dé la gana
¿qué podríamos hacer?
mira
pues ya que le hemos hecho
esto aquí
¿ves?
esto de let body
no sé qué
no sé cuánto
esto me lo voy a copiar
y vamos a crear este
que lo voy a transformar
voy a quitar esto
vamos a dejar el next
¿vale?
y vamos a decir
mira
si la request
es diferente al method
o sea que
al post
perdón
si el method de la request
es diferente a post
lo que vamos a hacer es
ir a la siguiente
punto
ahora
si los headers
el content type
es diferente
a application.json
esto es un ejemplo
porque podría haber casos
en los que esto no te interesa
y tal
pero bueno
es solo para que lo diferenciemos
para hacer el ejemplo
¿vale?
entonces
aquí
solo llega
request
que son
post
y
que tiene el header
content type
application.json
¿vale?
por lo que vamos a hacer
es tener
un middleware
para todas las requests
que pasen ahí
que son post
y que tiene el header
del content type
application.json
vamos a
extraer del body
escuchando el request
on data
vamos a transformar
el body
y cuando termine
lo que vamos a hacer
no va a ser
responder
porque esto no lo podemos hacer
lo que vamos a hacer
es
mutar
la request
y meter
la información
en el
rig.body
así que
lo que vamos a hacer
es mutar
esa request
porque la request
es una
para cada petición
¿vale?
este objeto request
que vamos a estar viendo
que está viajando
a otros sitios
es exactamente
la misma
que le va a llegar
más adelante
este objeto
es único
para cada petición
esto vas a ver
que es algo
que se repite
constantemente
en express
el mutar
la request
y cambiar el body
esto es una cosa
que se hace
o sea
internamente
en middleware
o que incluso tú
puede ser que hagas
porque te interese
pero es normal
porque las requests
son únicas
esta función
que le está llegando
la request
y la response
esto es para cada petición
¿vale?
esto no es un objeto global
que se cambia en la request
no
esto es la request
en específico
porque en esta request
tenemos la url
la ip
que la ha hecho
un montón de información
única
de esa request
¿vale?
así que con esto
hemos creado ya
un middleware
en el que estamos
extrayendo
para todas las peticiones
que sean post
estaríamos extrayendo esto
y ya no nos tenemos
que preocupar
vamos a quitar este next
de aquí
porque ya no tiene sentido
porque lo estamos haciendo
justamente aquí
y tendríamos
podríamos tener problemas
al decirle
que tiene que pasar dos veces
y ahora lo que sí que podemos hacer
es que aquí
fíjate
que todo lo que habíamos hecho aquí
ya no lo necesitamos
simplemente
ahora sabemos
que esto
funciona
que le podemos pasar
el rec.body
o sea
aquí vamos a tener
en la request.body
lo que hemos tratado
en el middleware
en toda esta parte
que hemos hecho aquí
hemos extraído
esa lógica
que era de
de una url
de un path en concreto
o de un endpoint
como lo quieras entender
lo hemos extraído
a un middleware
para poder reutilizarlo
súper fácil
en cualquier sitio
o incluso en cualquier proyecto
y ahora
ya simplemente
cuando hagamos un post
ya sea en Pokémon
o lo que sea
podemos revisar
fácilmente
request.body
porque ahí vamos a tener
la información
vamos a guardar los cambios
y vamos a probar
a ver si el request funciona
y fíjate
que de forma totalmente transparente
sigue funcionando
perfectamente
el 201
lo tenemos aquí
porque en el Pokémon
fíjate que le he dicho
que esto es un 201
y aquí tenemos
el request.body
aquí con el rigbody
deberíamos guardar
en base de datos
esto lo veremos
más adelante
en el curso
pero ves
aquí tendríamos
un ejemplo muy claro
de cómo utilizar
un middleware
y esto te funcionaría
para cores
por ejemplo
podrías arreglar
los cores con esto
podrías servir
archivos estáticos
podrías acceder
un montón de cosas
ese orden de request
Resinex es obligatorio
efectivamente
es obligatorio
porque son parámetros
que están ordenados
no son nombrados
si para que no sean obligatorios
tendrían que ser así
tendrían que ser así
pero sí que es obligatorio
porque son parámetros
por posición
no por nombre
así que
es importantísimo
que los dejes así
ahora que has visto esto
seguramente
mucha gente
que sabrá
un poquito de
de express
se estará preguntando
ostras
pero no veas
qué rollo
tener que hacer esto
obviamente
esto es un rollo
y por eso
cuando
lo voy a dejar aquí comentado
pero para que sepas
esto
lo puedes hacer
mucho más fácil
gracias a express
porque express
ya tiene un middleware
que te hace esto
puedes hacer
app.use
express.json
y esto
hace exactamente
lo mismo
que te he explicado
ahora
ahora
si haces un send request
esto está funcionando
exactamente igual
bueno
le falta lo del date
porque lo he quitado
porque es lógica
que estaba metido ahí
porque ves que el date
estaba aquí
lo del date now
esto lo podríamos meter aquí
pero exactamente
lo mismo que hemos hecho
viene ya
de forma totalmente nativa
en express
y ahora te preguntarás
pero tío
pero si viene
pero si viene
¿por qué?
¿por qué me has hecho
hacerlo desde cero?
para que lo entiendas
porque las cosas
que no sabes
de dónde vienen
son imperceptiblemente
no diferenciables
de la magia
y lo que quiero
es que sepas
cómo funcionan las cosas
si no sabes
cómo funcionan las cosas
el problema que tienes
muchas veces
es que no sabes
cómo funciona
express.json
qué es lo que está
haciendo por debajo
qué es lo que está pasando
cuando tienes problemas
no sabes de dónde vienen
y eso lo que significa
es tener un conocimiento
superficial
y yo lo que quiero
es que sepas
entiendas
y domines
no olvides
así que espero
y amigos
que os haya gustado
la clase
no hemos dado tiempo
a terminar el dotenf
en la próxima clase
seguiremos con
haremos el dotenf
veremos más middlewares
como el de static
que es bastante importante
veremos lo de
parsear argumentos
y veremos más cosas
hacer algo
lo de
a
haremos
en la próxima clase