logo

midulive


Transcribed podcasts: 746
Time transcribed: 15d 5h 20m 39s

This graph shows how many times the word ______ has been mentioned throughout the history of the program.

¡Muy buenas! ¿Qué tal? Bienvenido, bienvenida.
Espero que estés preparado porque hoy seguimos con el curso de Node.js desde cero
y además lo hacemos con MySQL.
Vamos a hacer MySQL desde cero, o sea que vamos a crear las tablas,
vamos a hacer todo eso desde cero, de la API que teníamos, que era de películas,
que ahora te explicaré para ponerte un poquito al día.
Vamos a ver como unas buenas prácticas en las que vamos a evitar mezclar código,
cuando ya vimos el patrón de MVC, hoy lo repasaremos un poquito por encima
porque es importante porque hoy creamos un nuevo modelo,
pero es que más adelante, además de que vamos a desplegar a producción
nuestra base de datos totalmente gratis, con un hosting que yo creo que te puede servir
para toda la vida, que no tienes que pagar nada, lo que sí que tienes que poner
tarjeta de crédito, pero no tienes que pagar nada.
Y vamos a ver, porque ese servicio más adelante lo volveremos a utilizar
de una forma más avanzada, pero lo que aprenderás hoy será súper fácil
para que puedas subir tu base de datos a producción.
Y además de eso, vamos a ver también una técnica, un patrón de diseño
muy importante que nos va a permitir que nuestra aplicación sea mucho más escalable
y mantenible el día de mañana y sobre todo testable.
O sea, estamos viendo buenas prácticas de cómo generar código, una API en condiciones
que vaya a durar a lo largo del tiempo.
Si por lo que sea te has perdido, te has perdido alguna clase,
el curso lo estamos haciendo totalmente de código abierto, ¿vale?
Aquí lo tenéis, mira, clase 1, clase 2, clase 3, clase 4.
Podéis descargaros todo lo del curso, en el código lo tenéis aquí,
lo descargáis, hacéis un git clone y os descargáis el código.
Y así podéis seguir todas las clases en el punto en el que lo dejamos al final.
Y así, pues no os liáis y decir, vale, pues si quiero empezar a clase 4,
pillo la clase, o sea, si quiero empezar a clase 5, me quedo en la clase 4
y a partir de ahí, pues puedo ir haciendo.
Vale, pues esto es el mismo repositorio que hay el mismo aquí en producción, ¿vale?
O sea, que no te tienes que preocupar que todas las clases están ahí y ya está.
De hecho, vamos a echarle un vistazo donde lo dejamos en la clase 4.
Vamos a abrir esto y tenemos clase 1, clase 2, clase 3, clase 4.
En la clase 4 hicimos algo súper interesante porque vimos el modelo vista controlador.
Es un patrón de arquitectura para separar como en capas o responsabilidades nuestro código.
En lugar de mezclarlo todo y en un solo sitio hacer la conexión a base de datos,
la validación de los datos, el devolver lo que tiene que renderizar los datos
y todo esto lo que se hace es separar en 3 capas.
Modelo, vista, controlador.
Donde el modelo, e hicimos una cosa muy chula, es que en el modelo teníamos ya diferentes modelos.
Teníamos un modelo que era el local file system,
porque esto era como lo primero que hicimos como para probar el local.
Y luego hicimos aquí uno de base de datos con MongoDB también.
Entonces nos conectábamos con MongoDB y funcionaba perfectamente y ya está.
Todavía nos falta enseñar la parte de la vista, pero bueno, es la menos importante.
La veremos más adelante, no te preocupes.
Lo que hicimos, entonces vamos a ver el punto de entrada.
El app.js.
Esto es un proyecto de express, fácil, que no tiene mucha historia.
Importamos express, creamos las rutas de las películas, de nuestra API.
Teníamos el course para arreglarlo, que también lo explicamos, cómo se arregla el course.
Y va mucho más allá de instalar un middleware y ya está.
Porque el problema de course es un tema de cabeceras que se arregla en la parte del backend, del servidor.
¿Vale? Importante.
Pues eso lo explicamos también.
Y lo que hicimos es empezar a crear ya todas las rutas de las películas.
Las rutas las teníamos aquí.
Teníamos aquí recuperar todas las películas, crear una película, recuperar una película por ID, borrar una película, actualizar una película.
Y estas rutas llamaban a un controlador.
El controlador era el que se dedicaba a decir, vale, cuando quiero recuperar todas las películas, llamo al modelo.
Que el modelo tú no sabes lo que hace.
Y esto es clave, ¿vale?
Esto es clave.
Tú el modelo no tienes que saber.
Si llaman a base datos, si lo guardan local, en memoria, no lo tienes que saber.
Y esta es una de las grandes claves en el mundo de la ingeniería de software y las buenas prácticas sobre esa abstracción.
Al final el modelo es como una caja negra que hace por dentro el trabajo que tenga que hacer.
Y lo importante es que se cumpla siempre el contrato.
¿Vale?
Que fue ese momento...
Oh, Dios, qué chulo.
Hoy os voy a enseñar una cosa que es súper importante para todos los niveles.
Y es muy fácil de entender porque no importas.
Con poco que sepas de JavaScript y sepas lo que es ya pasar por parámetros algo, te va a cambiar la perspectiva de muchas cosas.
Y desde junior hasta el final de los días como senior es una cosa que te va a ayudar un montón.
Así que estate atento y esto no te lo pierdas que te va a encantar.
Entonces, aquí en los modelos, fíjate que teníamos aquí el movie model.
Pero lo mismo que teníamos aquí el movie model este del local.
Podríamos importar el movie model de barra models barra database movie.js, el de la base de datos y debería funcionar exactamente igual.
¿Vale?
Debería funcionar exactamente igual, totalmente transparente, sin ningún tipo de problema.
¿Vale?
Entonces, vamos a dejar el local por ahora para no liarla porque creo que le quité el password para subirlo.
¿Vale?
Eso es lo que teníamos por ahora.
¿Qué pasa hoy?
Pues que hoy os voy a enseñar desde cero cómo podemos crear nuestra base de datos con MySQL.
¿Vale?
Para eso lo podemos hacer.
Así que lo que podríamos hacer aquí, igual que teníamos modelos database,
lo que podríamos hacer es cambiarle este, le vamos a llamar que este es MongoDB y tener un modelo que justamente sea el de MySQL y aquí, pues, movie.js.
¿Vale?
Vamos a crear nuestro modelo que lo que hace es conectarse a la base de datos de MySQL.
Entonces, lo que vamos a hacer es crear todos los campos, todas nuestras tablas de las películas,
igual que lo habíamos hecho aquí con el local file system, que claro, por ahora lo único que tenemos es un JSON.
Si os fijáis, si lo miramos por aquí, fijaos, si miramos el movies.json, ahora mismo lo que tenemos aquí es un JSON.
¿Vas a usar Dev Engine?
Sí, y ahora os lo explicaré también, que está súper, súper chulo.
Entonces, vamos a utilizar dos herramientas.
Podéis utilizar, claro, esto depende del sistema operativo y dependiendo de cada sistema operativo, pues, os gustará más uno u otro.
Yo voy a utilizar estos dos, pero yo os voy a recomendar otros y si no, la gente del chat, pues, puede decir, pues, utiliza este, utiliza el otro y ya está.
Yo voy a utilizar dos herramientas.
Una es Dev Engine, ¿vale?
Dev Engine.
Esta herramienta, que es totalmente gratuita, que está muy, muy chula, os va a permitir crear una base de datos súper fácil,
tanto de PostgreSQL, MySQL o Redis.
O sea, cualquiera de las tres, sin necesidad de pasar por la línea de comandos, la podéis utilizar.
La podéis encontrar Dev Engine y aquí la tenéis.
Esta tiene una versión para Mac y puede ser que no tengáis versiones para, a lo mejor no hay versión para Windows,
no tengo ni idea, así que detecta que es Windows.
Pero si no, pues, podéis buscar Dev Engine Alternative Windows y ya lo tendréis.
O si no, lo que podéis hacer, también lo podéis crear desde las herramientas de MySQL o lo que sea.
Pero hay un montón de alternativas que al final, con un clic, te generan la base de datos.
Así que lo podéis hacer así y ya está.
Yo utilizo esta porque es súper rápida y, pero seguramente, si no, ya la tendréis ahí.
Y si no, ¿puede ser la alternativa Diviver?
Puede ser.
Mira, Free Universal Database Tool.
Pues exactamente no me va a pinta y, además, esta lo que tiene es que podéis ver el tema de la UI.
Yo, en este caso, voy a utilizar el de MySQL porque me parece como la más típica.
También Laragon, Laragon.
Aquí tenéis otra, Laragon.
Modern Portfolio Easy Operation, ¿vale?
También lo tenéis esta, que esta sí que creo que está para otras, ¿no?
No solo está para Mac, esta la tendríais para otras.
A ver, Download.
Yo creo que sí.
O sea que tenéis un montón de alternativas.
Así que cualquiera que os sirve para crear la base de datos, lo podéis hacer o lo podéis hacer a mano.
La que queráis.
A mí me gusta un montón de Benjin porque, al final, la voy borrando, la voy creando y voy haciendo un poquito de todo.
Vamos a crear una de MySQL.
En este caso, como es local, en esta no nos vamos a preocupar mucho.
Lo único que vamos a decirle es que no la cree, que por defecto no tenga password.
Luego, como vamos a desbloquear y vamos a desplegar esto a producción, ya será más importante el tener password y todo esto y luego lo veremos, ¿vale?
Por ahora, vamos a iniciar esto.
Aquí, en Untitled, vamos a ponerle aquí.
Quiero poner que esto es Movies Database, ¿vale?
La base de datos de películas.
Le damos Start para que se inicie.
A ver si el puerto está libre, ¿vale?
Se inicia en el puerto 3306.
Y ahora, también, lo que podéis utilizar es MySQL Workbench.
La tenéis por aquí.
No sé, yo creo que en MySQL Workbench puede ser que también podáis crear...
La verdad es que creo que no.
Así sí, sí que se puede crear, ¿no?
O sea, que podéis crear también, a lo mejor, base de datos.
Yo MySQL Workbench nunca la he utilizado para crear base de datos porque me parecen como un poco más rollo
y me gusta tener tanto los de Postgre y Redis en el mismo sitio.
Y así aquí, pues, puedo ir viendo todas las que voy creando, si es de Redis o lo que sea.
Pero bueno, si os funciona MySQL Workbench, perfecto.
Una cosa importante de MySQL Workbench.
Amigos, MySQL Workbench, ¿vale?
Tened en cuenta, mucha gente cuando entra dice,
¡Ay, pero es que es de pago, que no sé qué, no sé cuánto!
A ver, tenéis que descargar la versión Community, ¿vale?
En este caso, ¿ves que pone MySQL Community?
Buscad MySQL Community y esa es la versión que tenéis.
La tenéis para todos los sistemas operativos y tal.
No os tenéis que preocupar, ¿vale?
Pero la versión Community no es de pago, es totalmente gratuita y lo importante es que no la leéis.
¿Qué es lo que vamos a hacer?
Vale, vamos a crear nuestras tablas desde cero, vamos poco a poco, vamos a decir, vamos a repasar otra vez.
Aunque os recomiendo que esto lo vimos más en detalle en el canal de Midulife.
Midulife, MySQL, ¿vale?
Tenemos que hicimos una base de datos de Twitter desde cero con MySQL y lo hicimos, las relaciones y todo esto.
Hoy la base de datos va a ser más sencilla, pero si quieres llegar a más, pues que sepas que ahí lo tienes.
Lo primero que vamos a hacer es crear la base de datos que le vamos a llamar MoviesDev.
Esto, esto será la creación de la base de datos.
Luego veremos que, claro, esto cuando lo vayamos creando vamos a tener que borrarla también, ¿no?
Ahora decimos que la queremos usar, ¿vale?
Así que decimos Use, bueno, en este caso creo que se suele utilizar así, pero bueno, vamos a poner Use y el nombre de la base de datos, ¿vale?
Utilizamos la base de datos MoviesDev.
Y ahora que tenemos la base de datos, lo que tenemos que crear dentro son tablas.
Muchas veces cuando hablamos de base de datos lo mejor es pensar a los archivos de Excel.
Al final lo que estamos creando con el Excel sería toda la hoja de cálculo y las tablas serían cada una de las hojas que tenemos en Excel, ¿vale?
Entonces ahora tenemos que crear la tabla Movies.
Nos vamos a basar en este fichero, ¿vale?
Este Movies.json, ¿veis?
Que tiene id, title y todo esto.
Nos lo vamos a copiar para que nos sirva de referencia.
Pero hay una cosa muy importante que no te puedes perder y que nunca puedes pasar de largo.
Fíjate que ya comentamos que este formato iba a ser un UUID, ¿vale?
Pues tenemos que intentar que siempre mantengamos esto, ¿vale?
Siempre tenemos que mantener esto.
Así que no lo vamos a fallar y esto lo vamos a pasar a MySQL.
Y así también vais viendo un poco cómo se pasaría algo a MySQL.
Vamos a crear.
Voy a poner aquí esto ahora de referencia.
Ahora lo elimino.
Pondríamos un Create Table, el nombre de la tabla y aquí tendríamos todos los campos.
Por ejemplo, el campo ID.
Ya veis que esto es un string que es un poco especial, ¿vale?
Alguien podría pensar que es un texto y tal.
Pero en este caso, en MySQL, para guardar los UUID, que sean los Universal Unique Identifier, ¿vale?
Pues lo que utilizamos en este caso sería un binario de 16 bits, ¿ok?
¿Por qué?
Porque esto lo podemos transformar tanto en cadena de texto como en binario y tiene sentido guardarlo.
Y así no lo vemos y cuando necesitamos lo veremos, ¿vale?
Así que esto será la llave primaria y le decimos que por defecto, podríamos poner por defecto o podríamos no poner por defecto.
Pero bueno, voy a ponerle un por defecto para que lo veáis.
Aquí por defecto tendríamos que crear el UUID.
Pero como lo queremos guardar, esto lo que va a hacer es devolvernos un texto.
Tenemos que pasarlo al formato binario.
Así que le decimos UUID to bin, ¿vale?
Y lo volvemos a poner así, ¿vale?
Con esto ya nos estaría creando la tabla ID, que decimos que vamos a guardar este binario.
Es una key primaria, ¿vale?
Es la llave principal, es el identificador único inmutable y por defecto va a tener este valor.
Así que si no se lo pasamos, ya le va a generar directamente el identificador con el UUID, ¿vale?
Aquí podríais utilizar un ID autoincremental, que sería mucho más sencillo.
De hecho, luego lo vamos a hacer en la otra tabla.
Pero bueno, este sería la forma como para satisfacer como lo teníamos antes, ¿vale?
Ahora los demás ya son más fáciles.
Por ejemplo, el title, sí que vamos a poner un varchar.
Bueno, podéis poner un varchar o podéis poner otros, pero bueno.
Vamos a poner 255, que me parece suficiente.
El año, un entero que no puede ser null, ¿vale?
Importante que también vayamos diciendo si pueden ser null o no pueden ser null.
Y esto tiene que ver con la validación de nuestros datos muchas veces, ¿vale?
MySQL no tiene el tipo UUID.
No tiene el tipo UUID, que yo recuerde.
A lo mejor en las nuevas versiones igual sí que lo tiene.
Pero yo creo que no tiene tipo UUID, ¿vale?
Yo creo que no lo tiene.
Pero bueno, da igual, porque en este caso podríamos guardarlo tanto como texto como binario.
Yo creo que en este caso seguramente mejor como binario.
Tendríamos el title, el gear, el director, ¿vale?
Otro varchar, not null.
Tendríamos la duración, que en este caso es un entero, que no es null.
Tendríamos el póster, que este es un texto.
¿Por qué?
Vale, ¿por qué no utilizo...?
Aquí le pongo un texto, pero realmente también podría ser un varchar, ¿no?
¿Por qué utilizo aquí el varchar y aquí texto?
A ver, normalmente el texto ocupa más espacios de memoria, ¿no?
¿Por qué?
Porque el varchar es como muy limitado.
Lo que estamos diciendo es, puedes guardar hasta 155 caracteres.
Y lo estamos limitando de alguna forma.
En cambio, cuando ponemos texto, estamos hablando más de un texto libre.
Voy a dejarlo como texto porque, claro, no esperamos que haya un título de una película
que sea más largo de los 155 caracteres.
Y entonces fallaría si intentamos guardar una película demasiado grande.
Y lo mismo con el nombre del director.
Pero bueno, si lo queréis simplificar, también podríais utilizar el text y no pasaría nada, ¿vale?
Y finalmente teníamos aquí el rate, ¿vale?
Que sería la puntuación.
Vamos a decir que es un decimal.
3, 1, not, null, ¿vale?
Aquí lo que estamos diciendo básicamente es la fijación.
Cuántos decimales puede tener, cuántos números puede tener y tal, ¿vale?
Le vamos a poner 3, 1, ¿vale?
Al decimal y que no puede ser null y ya está.
Ahora, nos falta lo del género.
El género, el tema es que esto, como es una asociación
que tenemos entre la película y el género,
tenemos que crear una relación.
Entonces, por un lado, tenemos que crear lo que sería cuántos decimales tiene, ¿vale?
O sea, tenemos que decirle, necesitamos que tenga...
Uy, espérate, que he puesto 3, 1.
Creo que alguien me lo estaba diciendo por ahí.
Pero la he liado, ¿eh?
Que he puesto 3, 1 y en realidad esto debería ser 2, 1, ¿no?
O sea, para que lo veamos, ¿no?
Bueno, igual 1, 1 ya sería suficiente.
A ver, este número sería la parte de la izquierda.
O sea, ¿cuántos números hay aquí?
En este caso solo queremos un dígito, ¿vale?
Y en este sería el de la derecha,
que en este caso solo queremos un dígito más.
Por eso, queremos un número y queremos aquí otro, un decimal.
Si le ponemos 3, 1, se supone que aquí deberíamos poder poner esto,
99,3, y no es el caso.
Así que yo creo que deberíamos poner 1, 1 y ya está, ¿no?
Lo que pasa es que es verdad que depende, ¿no?
Por ejemplo, si se le puede poner un 10,
entonces ya no necesitaríamos que realmente sea un 2.
Pero eso habría que ver, ¿no?
Si se puede o no se puede utilizar el 10.
Así que vamos a poner 2, 1,
que así nos aseguramos que funciona correctamente, ¿vale?
Y no tiene problemas.
Pero con 11 no hay 10, claro.
Claro, es que depende, ¿no?
Si el rating...
A ver, es complicado que una puntuación de 10 es complicado,
pero puede ocurrir.
Entonces vamos a evitarlo.
Vamos a evitarlo.
Pero bueno, ni el padrino tiene un 10, amigos.
Ni el padrino, la verdad.
Tendríamos que crear ahora una tabla.
Vamos a crear una tabla que sea para el género.
A ver, vamos a simplificarlo bastante.
Por lo tanto, vamos a ponerle una ID,
que sea un entero, que se autoincrementa
cada vez que añadamos una,
que esto va a ser la llave primaria.
Y luego lo único que vamos a tener es el nombre.
Normalmente esto sería bastante más complicado.
Vamos a poner que el nombre sea único
para que no podamos insertar dos géneros
que se llamen igual, ¿vale?
Porque eso no tendría sentido.
Así que vamos a poner que sea único.
Esto de único muchas veces tiene sentido.
Por ejemplo, cuando hicimos la base de datos de Twitter,
tiene sentido que el campo del nombre de usuario,
aunque no sea la llave primaria,
sea un campo único.
Porque no queréis que la gente pueda repetir
el nombre de usuario.
Pero a lo mejor el nombre de usuario
no es la llave principal, ¿vale?
Es súper importante que entendamos que hay veces
que una llave principal, obviamente,
tiene que ser única y tal,
pero hay veces que algo, un campo, puede ser único
pese a que no sea una llave principal,
como el nombre de usuario.
¿Y sabéis por qué no puede ser llave principal?
Esto déjatelo aquí.
Esto es de primero de base de datos, ¿eh?
Pero te lo cuento, ¿vale?
A ver, un nombre de usuario no puede ser nunca
un primary key.
No podéis utilizarlo como primary key.
Tampoco el email lo podéis utilizar como primary key
porque se puede cambiar.
O sea, el día de mañana el usuario puede decir,
oye, me quiero cambiar el nombre de midudev a Pepito.
Y el email lo mismo.
No podéis utilizarlo como llave primaria
porque el email lo puede cambiar.
Puede pasar de, oye, mi nombre es miduga.gmail
y lo pueden cambiar.
Entonces, los primary key, tened en cuenta esto, ¿vale?
Los primary key que utilicemos
tienen que ser no solo únicos,
sino que también tienen que ser inmutables en el tiempo.
Eso quiere decir que si una película la creamos
con una ID, siempre esa película tiene que tener esa ID.
Y lo mismo con los géneros, ¿ok?
Esto es importantísimo.
Importantísimo porque si no es una liada
y es algo básico cuando trabajas con base de datos.
Muy bien, continuamos,
que nos queda un poquito ya de la generación, ¿vale?
Tenemos la tabla género, tendríamos la ID y tal,
y ahora tendríamos que crear como la relación.
Que esto suele ser...
Ay, se me están olvidando aquí los puntos y coma.
Vale, pongo los puntos y coma, quitamos esto.
Básicamente para que, si por lo que sea algo me falla,
que me lo diga.
Creamos aquí el table movie genres, ¿vale?
Y aquí vamos a tener como la relación
entre las películas, qué géneros tienen.
Por ejemplo, el movie ID,
que esto va a ser un binario 16.
Esto es porque tenemos el UID de esta línea de aquí, ¿vale?
Por eso lo tenemos aquí, binario 16.
Esto referencia a movies.
A movies, no.
Movie, ¿no?
Movie.
He puesto movies o movie.
Esto diría...
Bueno, le podemos poner el nombre que queramos.
Vamos a ver movie, ¿vale?
Movies ID, ¿ok?
Y ahora lo mismo con el genre ID.
Esto va a ser un entero que hace una referencia al genre ID.
Y aquí el primary key va a ser el movie ID con el genre ID.
¿Vale?
Lo tendríamos por aquí.
Y ahí tendríamos justamente como las dos referencias, ¿no?
O sea, lo estamos cruzando, ¿ok?
Ahora tenemos una tabla donde vamos a poder decir la película tal tiene este género.
Y podemos tener más de una película porque van a tener diferentes géneros.
Porque si os fijáis, justamente era un array.
La...
A ver si os lo pongo por aquí.
El JSON...
Pam.
Lo tenemos por aquí.
¿Veis?
Podría ser un array donde pudiera tener más de una.
Para crear esto, ¿cuál es el problema?
Que MySQL, por desgracia, no tiene un array de forma nativa.
Así que en este caso tenemos que decirle, bueno, pues vamos a crear una tabla que sería como un anexo donde vamos a tener esta colección.
Donde cada película puede tener cada uno de los géneros a los que pertenece.
Así que sería una relación de muchos a muchos porque todas las... muchas películas pueden tener muchos géneros y muchos géneros pueden tener muchas películas.
Ah, y es verdad que me dice...
El Lord dice que el decimal debería ser unsigned.
Es verdad que no lo he puesto, esto, porque la verdad es que tampoco lo veía muy importante, pero ya está.
Esto sería la forma como de agrupar la información, ¿vale?
De las películas con los géneros.
No vamos a hacer las foreign keys y tal.
Si queréis ver las claves foráneas y tal, os dejo el vídeo porque no me parece tan importante en este caso, ¿vale?
Pero si queréis saber más de claves foráneas y todo esto, lo podéis ver en el vídeo que hicimos de la base de datos de Twitter, ¿vale?
Que estaba más tiempo.
Ahora lo que vamos a hacer ya es añadir datos para tener datos por aquí.
Así que vamos a añadir nuestros datos.
Vamos a insertar en género el nombre, vamos a poner los valores, el drama, ¿vale?
El drama sería un género, la action sería otro género, teníamos también crimen, teníamos también aventura, teníamos también ciencia ficción y romance, ¿vale?
Estos serían los géneros, ¿vale?
Y ahora ya podríamos insertar las películas, ¿vale?
Vamos a tener la ID, el title, el year, el director, la duración, el póster, el rate.
Obviamente no voy a añadirlos todos porque estaría aquí todo el día, así que vamos a añadir unos cuantos, ¿vale?
Vamos a añadir unas cuantas películas y así vemos cómo funcionaría.
Si os acordáis aquí, habíamos creado que el valor por defecto era el uuid, ¿vale?
Uuid.
Vale, pues vamos a poner aquí que la ID, aunque se lo he puesto por defecto, pero lo vamos a crear aquí a mano para que lo veamos.
Como ID, esto es posicional.
Aquí le estamos diciendo cada uno de los campos y ahora por posición le estamos diciendo,
quiero que me insertes en movie, la tabla movie, la película con ID y entonces en esta posición sería la ID.
En la siguiente posición sería el título, por ejemplo, de Interestelar, vamos a poner Interestelar, ¿vale?
Luego, la siguiente, el año, en la siguiente, el director, Christopher Nolan, ¿vale?
La siguiente, la duración, que no sé cuánto era, 180.
Luego el póster, bueno, el póster lo tengo que sacar, ¿dónde tengo el póster?
No sé si aquí.
Ah, mira, Inception, he pillado el póster de Inception, ¿vale?
Esto es del 2010 y el póster sería esto.
Luego tendríamos el rate, ¿vale?
Vale, pues vamos a poner el rate, vamos a ponerlo por aquí, tututu.
No sé si, bueno, está ahí un poco justo, pero se ve todavía, ¿no?
Y el rate le vamos a poner un 8,8.
A ver, que para mí es un poquito más, pero bueno.
Vale, esto mismo vamos a hacerlo con más películas, así que vamos a copiar esto.
¡Ay! Ahora, joder, con el scroll.
Está vivo el scroll, ¿vale?
Vamos a hacer, me quiero copiar esto.
Vale, ahora, venga, vamos a pillar, a ver, tengo esta.
Vamos a copiar esta peli, esto por aquí, 1994, de Frank Darabont, ¿vale?
Frank Darabont, 142.
Y le vamos a poner esta imagen, ¿vale?
Y ponemos una más y ya está, ¿vale?
Hostia, qué rabia me da que el scroll vertical, o sea, el scroll horizontal, no se hace con la mayúscula.
Sabes que muchas veces se hace con la mayúscula y en este caso no sé por qué no se hace con la mayúscula.
Bueno, lo haré con el teclado para que no me dé problemas.
Vale, esto por aquí.
Esto, le quitamos la coma.
Me queda una, vamos a poner The Dark Knight, el hombre de negro.
No, hombre, The Dark Knight de 1994, no creo que sea.
¿De 1994?
No creo, no creo.
Yo creo que esto está mal.
Yo creo que esto está mal.
No me puedo creer que sea de 1990.
No puede ser.
Debe ser, esa es la antigua, vamos.
La de Tim Burton puede ser, pero bueno.
Vamos a ponerle a esta un 9, ¿vale?
Bueno, con esto ya tendríamos aquí al menos las películas y ahora lo que podríamos insertar sería la relación de los géneros, ¿no?
Y tendríamos el Movie ID con el Genre ID.
Vale, como en este caso no tengo, podría mirar qué UUID se ha creado y tal, pero no lo puedo saber antes de que se cree, ¿no?
Entonces, vamos a hacer un poquito de trampa, pero bastante interesante porque así vamos a ver cómo podemos utilizar el Select para recuperar la película y así directamente meter el Movie ID recuperando desde el nombre de la película.
Por ejemplo, los valores que vamos a añadir aquí serían Select ID from Movie Where Title, ¿vale?
Y estamos haciendo aquí como consultas mientras estamos insertando, que esto es una cosa que en las clases anteriores no llegamos a ver y así está bastante bien porque puedes ir viendo, vale, pues no solo, no hace falta muchas veces que sepáis la ID.
Le podéis preguntar en MySQL cuál es la ID.
Por ejemplo, Inception, esto lo que nos va a devolver sería la ID y ya la tendríamos ahí.
Y lo mismo sería con el género.
Pero el género, aunque es verdad que esto es ID 1, 2, 3 y tal, tampoco hace falta.
O sea, aquí lo que podemos hacer también sería utilizar el Select para con el nombre saber la ID.
Esto no es lo que se hace normalmente.
Esto es porque nosotros estamos generando ahora la base de datos.
Ya más adelante, obviamente, siempre vas a querer utilizar las IDs.
Pero en este punto, para popular la base de datos, que es como se le dice, pues es normal que queramos hacer esto.
Vamos a poner algunas más, por ejemplo, Inception Drama.
Es un poco de aquella forma, ¿no?
Vamos a poner que es Syfy.
Vamos a poner también que es de acción, ¿vale?
Y vamos a copiarnos esta para poner también aquí, por ejemplo, Inception.
Vamos a poner esta película.
Esta sí que vamos a poner que es un drama, ¿vale?
Para que recupere lo de drama.
Y The Dark Knight y vamos a poner que es de acción.
Acción, ¿vale?
Muy bien, pues con esto ya más o menos, si más o menos lo hemos hecho todo bien, vamos a probar aquí con el Select y vamos a seleccionar todas las películas de Movie, From Movie, ¿vale?
Y ahora vamos a ejecutar todo el código SQL a ver cómo funciona.
Y entonces irá de arriba abajo, primero ejecutará esto, luego esto.
Si hay algún error, nos dirá, oye, he fallado aquí.
Y así, pues miramos si todo funciona.
Para ejecutar todo lo que hemos hecho, la creación de tablas y tal, le damos a este botoncito de aquí, ¿vale?
Vale, y hay un error.
Hay un error porque me dice que Genre ID no puede ser null.
Esto es porque...
¡Ay!
La he liado.
Mira, igual os habéis dado cuenta.
Igual os habéis dado cuenta y yo no.
Vale, veis que aquí he puesto el Select From Movie.
Esto está mal.
Esto debería ser del género, ¿vale?
Esto es de la tabla género, ¿vale?
Esto es el género, el género, el género, el género.
Y esto no es el title.
Esto es el name, ¿vale?
Así que ponemos name, name, name, name, ¿vale?
Además de esto, si el Select te vuelve más de un valor, la has liado.
La has liado, parda.
Claro, vas a querer evitar que devuelva más de un valor.
Vas a seleccionar solo el que realmente necesites, porque si no...
Dicho esto, ahora si intento volver a ejecutar esto, ¿vale?
Me va a dar otro problema.
Y es que me dice que no puede crear la base de datos Movies porque ya está creada.
Me dice, oye, es que ya está creada, ¿vale?
Me está dando ese error ahí.
Me está diciendo que ya está creada.
Muy bien.
Lo que pasa con esto es que tenemos que eliminar la base de datos antes de crearla otra vez.
Porque como ya existe, si intentamos ejecutar el mismo código.
Así que le decimos que haga un drop de la base de datos si existe Movies Database.
Todo esto que hemos hecho es importante porque nos va a servir cuando hagamos el despliegue a producción
de nuestra base de datos ejecutar todo este código para tener ya también en producción,
aunque sean las tablas vacías, tenerlas.
No va a ser tan importante los inserts y todo esto, aunque también lo podríamos hacer.
Pero bueno, al menos para tener información también en producción lo podríamos hacer
para no empezar de cero, especialmente con los géneros, ¿vale?
Vale, vamos a probar otra vez, a ver si ahora le gusta esto más.
Vamos a darle, ping, vale.
Y ahora sí, parece que se ha creado todo correctamente.
Fijaos que aquí nos va dando todos los checks, ¿vale?
Si ha ido bien, si ha ido bien, si ha ido mal, ¿vale?
Aquí me dice que hay un warning con un unsign.
Que mira, justamente me dice que unsign no le estaba gustando.
Pero por lo demás, aquí tenemos todos los checks, todo ha ido bien.
Y ya ha hecho un select al final como, vale, pues este select que hemos hecho aquí me lo está enseñando.
Y fijaos que tengo la ID, el title, el gear, el director, duración, poster, rate.
Ahora mucha gente seguramente se asustará y dirá,
¡Ostras! Pero mírate, la ID esta, esta ID no la puedo ver, ¿sabes?
O sea, ¿ahora qué pasa con la ID?
Me habías dicho que era una cadena de texto y no es una cadena de texto.
O sea, ¿ahora qué pasa? No puedo ver esta cadena de texto, esto es un rollo.
Vale, no te preocupes.
Porque lo que vamos a hacer con esto, básicamente, es indicarle de una forma
que nos lo pase a una cadena de texto que vamos a entender.
Y esto es importante porque nuestro backend lo necesitamos justamente así.
Así que vamos a seleccionar todo y aquí vamos a decirle bin to uuid
y le decimos que el campo ID nos lo transforme, ¿vale?
Entonces vamos a recuperar todos los datos, pero la ID, ¿vale?
Le ponemos el nombre aquí ID, queremos que haga esa transformación.
Fíjate que ahora si ejecuto solo esta línea y eso lo consigo dándole a este botoncito,
le doy a este botoncito, ¿vale?
Fíjate que ahora aquí, aunque es verdad que me sale dos veces, ¿vale?
Pero podría recuperarlos todos.
O sea, podría poner aquí title, los podría poner todos para evitar esto, ¿eh?
Title, year, director, duration, poster, rate, ¿vale?
Y ahora con esto ya lo tendríamos bien.
Fíjate que lo tenemos aquí perfectamente.
Ahora sí que está mostrando correctamente esto.
Lo que estoy viendo es que me lo ha creado con la misma idea, ¿no?
¿Puede ser que esto me esté creando la misma?
Sería un poco raro, ¿no?
Pero me lo ha creado con la misma.
¿O se parece?
Ah, no, se parece.
La madre que lo parió.
Hostia, es que solo es la primera parte.
¿Sabéis por qué?
Hostia, me ha costado verlo.
Claro, digo, hostia, que me lo está creando la misma.
Claro, puede ser que muchas veces los identificadores únicos funcionan con diferentes grupos, ¿no?
El primer grupo puede ser el timestamp o algún tipo de algo generado con el tiempo.
El segundo grupo tal.
O sea, que puede tener diferentes grupos y por eso justamente pasa, ¿vale?
Pero no, no.
Son diferentes.
Lo que pasa es que son muy similares.
Son muy, muy, muy similares, ¿vale?
Por eso justamente parecía que era lo mismo.
Pero bueno, con esto al menos ya tenemos nuestra base de datos.
Ya podemos continuar y vamos con el código, ¿vale?
Y instalamos las dependencias para hacer la conexión con nuestra base de datos.
Vale.
Vamos a copiar, copiar la clase 4 a la clase 5.
Y así la clase 4 la dejamos igual, ¿vale?
Nos vamos aquí, abrimos esto en el editor, así nos enfocamos con esto.
Y fíjate, lo primero que vamos a hacer, y esto es una de las cosas maravillosas, y por lo que entenderás que es tan importante y tan interesante lo que hicimos la otra vez,
es que en los modelos, veis aquí MySQL.
O sea, claro, el MySQL lo he creado ahora.
Teníamos local file system, MongoDB y MySQL.
Bueno, pues el de MySQL este es el único que vamos a tocar ahora.
Y lo que podemos hacer es basarnos en el MongoDB este, ¿ves?
Que aquí hicimos un montón de cosas ya con la conexión.
Bueno, pues esto nos lo vamos a llevar aquí.
Y lo que vamos a hacer es quitar todas las referencias de Mongo.
Todas las referencias de Mongo.
Todo esto, fuera.
Todo esto, fuera.
Esto, fuera.
¿Vale?
No queremos saber nada de lo que hace.
Fuera, fuera, fuera, ¿vale?
Y esto también, fuera.
¿Vale?
Lo único que nos queremos preocupar es que nuestra nueva conexión a MySQL tiene que saber esto, ¿vale?
Que tiene que hacer esto, el getById, el create, el delete.
Y lo único que nos interesa es este código de aquí.
Bueno, pues lo primero que vamos a hacer aquí sería un pnpminstall.
Y ahora, aquí hay una recomendación.
Mucha gente, porque a lo mejor no lo sabe, pero mucha gente, cuando busca MySQL Note, utiliza este de aquí.
Pero, a ver, amigos, hay un problema con esto.
Fijaos que está publicado de hace cuatro años, ¿vale?
Y esto, que todavía se descarga un montón y que funciona bien, ¿eh?
Que no hay ningún problema, ¿vale?
Un millón de descargas.
Es de hace cuatro años.
La biblioteca que yo recomiendo para hacer de driver nativo, para conectarte a MySQL Note, sería MySQL 2.
Se llama así, MySQL 2.
Porque además de que es más rápido, está más actualizado.
Fíjate, este se ha publicado hace un mes.
Este está más descargado.
Está basado en el original, ¿vale?
Pero este sería el correcto.
El otro, no es que vaya mal, pero no os lo recomiendo, porque ya hace bastante tiempo que no se actualiza y utilizaba versiones muy antiguas de algunas cosas de Note y no tiene mucho sentido.
Entonces, súper importante no cometáis este error.
Vamos a utilizar PNP install para instalar esta dependencia en nuestra clase 5, ¿vale?
Esto no debería tardar mucho.
No hay soporte, sí, no hay soporte.
SQLize es diferente, ¿vale?
Y eso lo veremos más adelante de temas de WordRM y todo esto.
Muy bien, entonces, con esto, lo único que tenemos que hacer es irnos a nuestro modelo, ¿vale?
Y vamos a hacer import MySQL from MySQL 2, ¿vale?
Y aquí vamos a crear nuestra configuración de conexión.
¿Cuál es la configuración de conexión?
Le tenemos que decir, por un lado, cuál es la URL, o sea, el host, el hostname, el usuario, que en este caso es root.
No tenemos password, en este caso, o sea, lo podríamos dejar vacío.
O lo, no sé si dejarlo vacío, o sea, no pasárselo directamente.
Vamos a pasárselo vacío porque igual se queja si no se lo pasamos.
Y la base de datos, ¿vale?
Que en este caso, la base de datos, tendríamos que ver cuál es el nombre que le hemos puesto a la base de datos,
que es moviesdb, ¿vale?
Pues le ponemos el moviesdb.
No sé si el nombre de la base de datos...
Voy a cambiarle por si...
Para ponerle mismo, ¿vale?
Y ya lo tendríamos, ¿vale?
Bueno, esta sería la base de datos, esta es la configuración.
Vamos a conectarnos.
Y para eso hacemos un connection y hacemos MySQL, Create Connection, y ya le pasamos la configuración.
El Create Connection, esto crea una conexión y ya podríamos empezar a utilizar aquí en connection y hacer, pues, lo que queramos.
Podríamos hacer una ejecución, una query, aquí select, no sé qué, no sé cuánto, seleccionar, no sé qué, ¿vale?
¿Qué pasa con esto?
Pues que esta API, esto es un rollo, porque esto te obliga a utilizar los callbacks, ¿vale?
Y esta forma no está mal, o sea, funcionar funciona, pero es un poco un rollo.
¡Ay! Me falta el puerto, ¿eh?
Perdona.
Es cierto, me falta el puerto, que es 3306, ¿eh?
3306.
Ahí dice, hay que usar Promissify, dice Matías.
La verdad es que no hace falta utilizar Promissify, ¿vale?
Y os voy a explicar por qué. Por suerte, MySQL 2 es una biblioteca nueva, moderna, que tiene promesas, ¿vale?
Entonces, aquí le ponéis barra Promiss y ya lo tenéis arreglado.
¡Tintín!
Y ahora podéis utilizar aquí Promesas, ¿vale?
Hacemos una wait.
Entonces, esta conexión ya la dejamos aquí, como que sea algo que podemos reutilizar en todos los sitios.
Y aquí, por ejemplo, ya para recuperar todas las películas, vamos a simplemente hacer un Select All, ¿vale?
Vamos a tener aquí Const Movies.
Bueno, esto tendría el resultado, ¿vale? Para que lo veamos.
Y aquí hacemos una wait con el connection Query.query, ¿vale?
Y tendríamos Select Bean To.
Esto es lo mismo que he puesto aquí, ¿eh?
O sea, esto me lo estoy copiando básicamente de aquí del final, ¿vale?
Que he hecho, mira, me lo voy a copiar del final.
¿Veis esto que había hecho aquí?
Pues esto me lo voy a copiar, que sé que funciona.
Lo ponemos aquí, ¿vale?
Y ahora ya tendríamos aquí los resultados.
Vamos a poner un Console Log con el Result.
Y esto ya lo podemos probar.
Así que vamos a nuestra API.http, que esto es una forma de poder hacer requests
y tenerlas documentadas en las requests.
Esto es una extensión de Visual Studio Code, que básicamente lo que hace es un Get de este Endpoint.
Y al menos ahora podríamos probar esta.
Pero claro, antes de probarla, tenemos que asegurarnos que estamos utilizando este modelo.
Así que lo que tenemos que hacer es volver a nuestro controlador,
que es el que tiene la información del modelo.
Aquí estamos utilizando, fíjate, el Local File System.
Esto lo quitamos de aquí, ¿vale?
Y lo que vamos a hacer es importar el Movie Model, pero el de MySQL.
Solo con este cambio ya estamos cambiando.
¿De dónde saca la información?
Si de Mongo, de MySQL o del archivo de la memoria.
Solo con el cambio de una línea de código.
Normalmente, mucha gente, seguro que os ha pasado muchas veces, ¿no?
Que tenéis que hacer un cambio así de un repositorio y luego decís,
ostras, es que hay que hacer cambios en todos los sitios, la migración es muy complicada.
Pues fijaos que en este caso lo que hemos hecho es simplemente,
estábamos haciendo esto, le decimos, vale, pues ya está.
Solo cambias el modelo y ya está, ¿vale?
Muy bien, pues con esto teníamos ya la conexión.
Dejamos aquí el resultado.
Vamos a mirar si el resultado funciona.
Vamos a levantar el servidor, ¿vale?
Vamos a levantar el servidor.
Le ponemos el watch para que se reinicie cada vez que lo hacemos.
Le ponemos, esto se inicia en el punto de entrada que es el app.js.
Parece que funcionar funciona.
Vamos a abrir nuestro app.http.
Vamos a enviar la request, ¿vale?
Y no ha funcionado.
Vale, no ha funcionado porque no está haciendo el doble return.
Pero sí que tenemos aquí el resultado, ¿vale?
Fijaos que he hecho un console.log aquí.
Aquí he hecho un console.log del result, este console.log result, ¿vale?
Y lo tenemos aquí.
¿Cómo funciona esto?
Lo que funciona es que el resultado es lo que sería una tupla.
Es una tupla de dos elementos, es un array de dos posiciones.
Donde la primera posición tenemos el resultado de la query, ¿veis?
Tenemos aquí el resultado de la query.
Y la segunda posición es como la información de la tabla, en este caso.
Nos está dando toda la información de la tabla, ¿vale?
Bueno, pues lo que vamos a hacer aquí es utilizar la desestructuración, ¿ok?
Y decimos, vale, pues el primero tenemos las movies y aquí sería el table info, ¿vale?
Table info.
Bueno, pues vamos a poner que el primer resultado es movies y directamente aquí ya podríamos devolver movies.
Movies, devolvemos movies, vamos aquí a la API, send request y aquí ahora ya podemos ver que ya nos hemos conectado correctamente a nuestra base de datos y ya está haciendo toda la información que estamos sacando.
Te voy a dejar de ejercicio que hagas el recuperar todas las películas por género.
¿Qué es lo que te voy a mandar de deberes?
Mira, todo lo que necesitas para solucionar esto, que no es difícil, ¿vale?
Por ejemplo, aquí nos faltaría que si tenemos un género, te voy a dar un poquito de pistas, ¿vale?
Pero no lo vamos a terminar, aunque tendrías que hacer el john y tal, pero eso lo podéis solucionar viendo mi vídeo de Twitter de YouTube.
No lo vamos a hacer hoy porque es bastante, no es que sea difícil, pero sí que es largo, tenemos que hacer unas cuantas cosas y eso, ¿vale?
Lo primero, tendríamos el lowercase genre, deberíamos aquí, pues, get genre ideas from database, ¿vale?
Usando el nombre, en este caso, using genre names, porque claro, el filtro, fíjate que era con el nombre.
En este caso, como es con el nombre, pues lo tenemos que hacer aquí.
Entonces, tendríamos que recuperar aquí los géneros de la conexión con la query.
Aquí seleccionamos la id, el nombre, from, where.
Aquí podemos utilizar el lower para comparar con el tema de lowercase, que el lower donde el nombre lo pasamos todo a minúsculas.
Y así nos aseguramos que no tenemos un problema de case sensitive, ¿vale?
Porque imagínate, veis aquí que nos lo estaba pasando todo en mayúsculas.
Así ya nos olvidamos y nos pasan mayúsculas, minúsculas, una en alto, una en otra abajo y tal.
Si lo que hacemos es igualarlo y lo comparamos todo en minúscula.
Y así nos aseguramos que lo vamos a buscar y lo vamos a encontrar correctamente.
Así que ahora con esto, al menos lo que tendríamos, ¿vale?
Aquí teníamos el lowercase genre.
Con esto, ya lo que tendríamos los géneros de si este género existe.
Porque aquí, obviamente, si el género no es genre found, ¿no?
Si los géneros aquí, el length, es igual a cero, deberíamos devolver que no hay películas.
Porque si no se encuentra el género, es que no hay ninguna película.
¿Vale? Todavía aquí tendríamos que get the id from the first general result.
¿Vale? Tendríamos que tener el primer resultado, ¿no?
Que para saber aquí la id del primero, al final lo voy a hacer yo en un momento, ¿vale?
¿Vale? Aquí sería el primer id del género.
¿Por qué? Porque queremos filtrar, por ejemplo, de acción.
Y aquí ya podríamos recuperar la id.
Y a partir de la id, pues, get all movies ids from database table.
Bueno, aquí tendríamos que hacer la query a la tabla esta que hemos hecho, que sería el moviegenres, ¿vale?
A query, a moviegenres, el join y devolver resultados, ¿vale?
Y ya lo tendríais.
No es complicado, es un poco laborioso.
Y os dejo el vídeo, es que lo vais a aprender con el vídeo.
Y así os dejo un ejercicio, que muchas veces me decís, déjanos un ejercicio.
Pues aquí os dejo un ejercicio y además está muy chulo para que lo consigáis.
En este vídeo, creando la base de datos de Twitter, aquí, con lo que aprendéis ahí, lo vais a poder hacer sin ningún problema, ¿vale?
Y ahí tenéis la tarea y os vais a divertir, que está bastante chulo.
Así que, os dejo esto por aquí.
Por ahora voy a poner un retur vacío, ¿vale?
Para que no nos pete.
Y entonces ahora, esto, pues, debería de volver...
Ah, ha petado algo, porque algo hemos hecho aquí de un inchis.
Vale, action...
You have an error in your...
Check the manual with lower name action...
A ver, espérate, que algo he hecho aquí mal, ¿no?
¿Qué he hecho mal aquí?
Select name from...
Ah, claro, from...
Aquí el from se me ha olvidado.
El from genre, ¿vale?
Donde lower name y tal.
Vale, os voy a explicar y voy a aprovechar a explicaros cómo funciona este cliente de MySQL.
En este caso, ¿veis aquí que hay un interrogante?
Bueno, este interrogante lo que hace es como una interpolación.
Lo que estamos haciendo es, por un lado, tenemos la query, que sería esta de aquí,
y en la query le estamos dejando unos interrogantes.
Estos interrogantes los va a ir reemplazando por los valores que le vamos a pasar a este array.
Entonces, en el primer interrogante que encuentre, lo va a reemplazar con el valor del primer elemento de la array que encuentre.
El segundo interrogante, pues lo reemplazará con este.
El tercer interrogante con este otro, ¿vale?
¿Entendéis?
Así es como lo va a ir reemplazando.
Y por qué es importante, y esto sí que es clave para que evitéis problemas, ¿vale?
¿Por qué es importantísimo que hagáis esto y lo hagáis por posición?
Porque alguien me podría preguntar, hombre, Midu, ¿pero por qué no lo haces así?
¿Por qué no haces esto?
Si es mucho mejor, ¿no?
Hacerlo así.
Esto es lo peor que puedes hacer en la vida, ¿vale?
Y esto es básicamente una inyección de SQL.
Lo que va a ocurrir aquí, lo que está pasando aquí, ¿vale?
Es que le estás dando rienda suelta a que el usuario, desde fuera, te inyecte lo que le dé la gana.
Por ejemplo, aquí vamos a mirar si...
A ver si lo podemos ver, ¿vale?
Si pongo aquí...
A ver...
Vais a ver hacking...
A ver...
Un no action...
Como no lo estoy haciendo bien, pues encima le tengo que pasar aquí las cosas estas, ¿vale?
Vale...
Esto por aquí...
A ver ahora...
A ver ahora...
Vale...
Vale...
Sale vacío, ¿vale?
Sale vacío...
Pero el tema es que el problema que hay aquí es que en Lowercase Genre lo que estaríamos haciendo es que alguien intentase hacer esto.
Select all from...
O bueno, select por decir algo, pero drop table...
Drop table normalmente no se puede porque el usuario que vamos a hacer la conexión no le damos este tipo de cosas, ¿no?
Pero le podríamos poner aquí alguna cosita, select from movie, por ejemplo, select para ver información de que no debería tener acceso, un delete, un update, un insert, darle al usuario, darle algún tipo de permiso.
Y esto, como lo estamos evaluando tal cual, aquí lo que estamos haciendo es una SQL Injection.
Nos están inyectando comandos SQL.
Este seguramente es uno de los ataques más antiguos del mundo, más típico cuando hablamos de MySQL.
Pero es bastante potente, así que tienen que tener mucho cuidado.
Para arreglarlo, muy sencillo.
Lo que le decimos es, oye, aquí va esto y ya lo que va a hacer el cliente de MySQL es que automáticamente, sin ningún tipo de problema, ya se va a encargar de evitar este tipo de inyección.
¿Cómo?
Pues lo que va a hacer aquí es que lo va a transformar a una cadena de texto, ¿vale?
Porque realmente no va a permitir que sea una query, una consulta, sino que lo va a transformar directamente a una cadena de texto que no se puede evaluar, ¿ok?
Entonces, lo tenéis que hacer así siempre, siempre.
No os olvidéis, siempre.
Muy bien.
Entonces, vamos con el siguiente, que el siguiente es facilito.
El getById.
¿Vale?
GetById, pues nada, es parecido al que hemos hecho antes.
Mira, de hecho, lo tenemos aquí, ¿no?
Tenemos este select movie, tal, bueno, pues el getById, lo copiamos, lo que simplemente vamos a cambiar.
Le voy a poner un template string, pero para poner salto de línea, ¿vale?
Así se entenderá mejor.
Ponemos el from movie y el from movie donde la id sea uuid to bin, ¿vale?
Y aquí es donde vamos a inyectarle realmente nuestro campo.
Y aquí le pasamos la id.
Y lo único que hacemos es, si no tenemos películas, devolvemos null y si no, devolvemos la película que ha encontrado, en este caso.
¿Vale?
En esto vamos a ver si esto funciona, si recuperamos todas las películas.
¿Vale?
Aquí tendríamos esta id.
Vamos a ver si recuperamos Inception.
Así que recuperamos una película aquí, con Inception, sin Request, ¿vale?
Y aquí la tenemos, ¿vale?
Sin ningún problema.
Perfecto.
Recuperar todas las películas por un género.
Esto ya hemos visto que lo tendríais que hacer vosotros, ¿vale?
Que os queda ahí como ejercicio.
Crear una película.
Bueno, crear una película.
Crear una película, pues tenemos que hacer el Insert también exactamente igual.
Lo que es importante es que tenemos que recuperar todos los campos del Input, ¿no?
Aquí en el Input, en las validaciones que hicimos en la clase anterior, fijaos, teníamos aquí en Esquemas cómo tendríamos que pasarle la información.
El Title, el Year, el Director, la Duración, Rate, Poster, los Géneros.
Todo esto lo teníamos aquí, ¿no?
Lo primero que vamos a hacer es el Genre, lo vamos a ignorar, pero esto en realidad lo podríamos leer y enviarlo de otra Genre is an Array.
Esto habría que insertarlo manualmente, ¿no?
En la relación.
Eso se podría hacer.
Lo que vamos a hacer es sacar, por un lado, todos los demás.
O sea, tendríamos el Title, el Year, la Duración, el Director, el Rate, el Poster, ¿vale?
Esto sí.
Y ahora tendríamos aquí un Insert, donde hacemos, aquí tendríamos Insert Results.
Bueno, no voy a hacer lo de los géneros, lo voy a dejar a vosotros, todo el tema de los géneros.
Y así vamos a enfocarnos solo en el de las películas.
Os voy a explicar cómo podríamos insertar esto si no tuviésemos el valor por defecto.
Que entiendo que, como tenemos el valor por defecto, lo vamos a intentar con el valor por defecto.
Si os acordáis, cuando hemos creado la tabla, ¿veis?
Aquí hemos puesto que por defecto debía tener esto.
Así que podríamos no pasarle la ID.
Podríamos no pasarle la ID.
Pero, ¿qué pasa?
Que si nos fijamos en el modelo que teníamos, por ejemplo, aquí,
los modelos siempre tienen que tener el mismo contrato, tanto de entrada como de salida.
Por lo tanto, aquí estamos devolviendo la película que estamos creando.
¿Qué es lo que pasa?
Que si se genera dinámicamente la ID, el problema es que no sabemos cuál es la que se ha generado,
porque no la podemos recuperar.
Y de hecho lo vais a ver ahora.
Mira, lo vamos a ver para que veáis que esto puede ser un problema.
Vamos a hacer el insert, ¿vale?
El insert, que me lo voy a copiar de aquí.
Este insert, ¿vale?
Pues este insert lo vamos a poner aquí.
Await connection.query, ¿vale?
Con este insert.
ID title, ¿vale?
El ID lo voy a quitar, ¿vale?
Vamos a dejar los values.
Los values vamos a ponerlo aquí debajo para que lo veamos bien.
Aquí vamos a utilizar, pues otra vez, el...
Bueno, aquí tendríamos el title, la película, ¿vale?
Ahí tenemos todos y aquí le pasaríamos el title, el gear, director, le pasaríamos todos los campos.
¿Qué pasa?
Que esto tiene un resultado y normalmente...
Vamos a hacer un console.log.
Normalmente podemos recuperar la ID que se ha insertado, pero vas a ver que esto no funciona.
¿Vale?
Vamos a intentar insertar esta película, ¿vale?
Ah, fijaos que aquí teníamos esto de SQL.
Esto era para demostrar que no nos podían inyectar SQL, ¿vale?
Y lo vais a ver ahora que este SQL, aunque nos lo pase, no funciona, ¿no?
O sea, que no pasa nada.
Nos pueden pasar lo que queramos porque como tenemos el esquema que hicimos en la clase anterior aquí,
esto directamente ya lo que hace es validar los datos que son correctos
y evitar que campos que no están informados no los meta directamente en la base de datos.
Pues aquí, en este insert, que tenemos aquí el title, gear, director, duración, poster y estos valores,
pues lo que vamos a hacer es un console.log para ver el resultado
y vais a ver un poco el problema que tenemos por aquí, ¿vale?
Vamos a intentar llamar nuestra API con el insert, hacemos el post.
Aquí da un undefined, este no es importante, pero fijaos aquí en la información.
Me dice, fill count 0, ¿vale?
Tiene sentido, affected rows 1 porque se ha afectado justamente una fila.
Insert ID 0, me está devolviendo un 0, pero si miramos aquí en nuestros esquemas, ¿vale?
Vamos a ver la tabla y vamos a ver que en las películas ha añadido la película,
con el nombre repetido, obviamente, ¿no?
Que debe ser The Good Father.
Ah, no, esta es la que hemos añadido, The Good Father.
Sí que tiene correctamente un ID, que no es 0, que es otro, ¿vale?
Tiene el RAID también, perfecto.
Pero, ¿cuál es el problema?
Pues el problema es que ahora no podemos recuperarlo
porque el result ID, este insert ID, solo te lo devuelve cuando son autoincrementales.
Midu, ¿qué opciones de usar?
Sequelize y tal.
Amigos, os voy a decir una cosa, que no paráis con el tema de ORMs.
A ver, los ORMs son geniales.
Yo seguramente para una, para algo, Sequelize, el que queráis, el que os dé la gana, cualquier ORM.
Hay un montón hoy en día.
Pero cualquier ORM está genial.
Lo que pasa es que aprender un ORM es algo que muchas veces es más temporal.
O sea, son cosas que van y vienen.
Un ORM va y viene.
¿Por qué?
Porque ahora tenías Sequelize y de repente sale Prisma, lo tienes que aprender de nuevo y tal.
Pero es que lo que estamos aprendiendo hoy te sirve para todos.
Y es súper importante.
Estas son las bases que son súper importantes a la hora de utilizar cualquier ORM,
aunque muchas veces te abstraiga de esto,
porque entiendes cómo están funcionando las cosas por detrás.
Pero podéis utilizar el que os dé la gana.
Todos los ORMs al final están muy bien, ¿no?
Es azúcar para lo que estás haciendo.
Claro, efectivamente.
Y está bien, pero el azúcar, muchas veces el problema que tenemos es que te puede afectar negativamente, ¿vale?
Cuando tomas mucho azúcar, porque ya no sabes cómo funcionan las cosas.
Y cuando tienes un problema, entonces empiezan los problemas de verdad, porque no sabes de dónde vienen, ¿vale?
¿Por qué usar UUID versus autoincrement?
Bueno, porque a veces tiene sentido.
A ver, el autoincrement a veces tiene sentido.
Hacer una IDE que se autoincremente puede tener sentido cuando el identificador no es importante en cuanto a que sea algo privado.
Por ejemplo, para un usuario no tiene sentido utilizar un autoincrement.
¿Por qué?
Porque eso hace que sea predecible cuál es el siguiente IDE.
Si alguien crea un usuario y es el 4 y el siguiente es el 5, es predecible que el siguiente es el 5.
Y eso hace que sea incluso, pueda ser un problema de seguridad.
Entonces, si el identificador de alguna forma no quieres que sea predecible, no puedes utilizar autoincrement.
Luego también está un tema del cómo crece, si vas a dejar huecos por ahí.
Normalmente el UUID, el identificador universal único, suele servir bastante porque te solucionan muchas papeletas, pero no es predecible.
Si necesitas que sea predecible, pues utilizas el otro y ya está.
Entonces, este sería el insert.
Ya veis que lo he insertado, pero hemos perdido la posibilidad de saber cuál era el UUID.
¿Vale?
Bueno, lo que vamos a hacer con esto es que vamos a crear nosotros el UUID aquí.
Normalmente aquí podría ser bastante complicado, ¿no?
Porque dices, ostras, ¿cómo lo creo?
Podrías utilizar, por ejemplo, cripto.randomuid, ¿vale?
Podríamos utilizar un montón de cosas.
Pero una cosa que muchas veces no utilizamos, que es interesante, es que podemos utilizar también MySQL.
O sea, podemos llamar a MySQL para que lo genere.
Por ejemplo, podríamos, uno, traerlo aquí, tener el UUID result, ¿vale?
Y aquí llamar a SQL para decirle que quieres seleccionar un UUID.
Y esto va a ser UUID, ¿vale?
Y aquí ya lo podría recuperar.
O sea, podríamos tener aquí, recuperar el UUID de este resultado, del UUID result,
y este UUID pasárselo por aquí.
¿Por qué lo hacemos aquí y no hacemos el SELECT directamente aquí dentro?
Porque vamos a necesitar aquí utilizarlo para cuando hagamos el SELECT.
Y aquí lo perderíamos igualmente.
Lo haríamos en una, pero lo perderíamos.
No seríamos capaces de recuperarlo.
Así que lo que hacemos aquí, ¿vale?
Es UUID to bin, que lo tenemos que transformar en binario.
Esto lo dejamos aquí y aquí ponemos el UUID, ¿vale?
Así.
Este, mira, en este caso, para que veáis cuándo es interesante aquí,
sí que podríamos aquí, por ejemplo, hacer esto.
¿Vale?
Aquí sí que podríamos hacer esto, si quisiéramos.
De hecho, mira, lo vamos a hacer.
Aquí sí que podríamos hacer esto.
Y esto a veces es interesante saber cuándo puedes y cuándo no puedes hacer ciertas cosas.
Aquí sí que podrías hacer esto porque esto es una cosa que tú en el backend estás dominando.
O sea, aquí no estás dejando que sea el usuario que te informe el UUID.
Esto lo estás generando tú.
Está como en un entorno seguro en el que directamente aquí realmente sí que te aseguras
que aquí no te van a inyectar nada porque eres tú el que lo estás generando, ¿vale?
O sea, aquí sí que tendría sentido.
Hay veces que sí que puede tener sentido y que lo puedes hacer tú sin ningún problema
y hay otras que no.
Pero aquí lo podrías hacer, ¿vale?
No es una variable que te viene del usuario, que es peligrosa y tal,
sino que aquí directamente sí que es un identificador que has creado tú
y aquí lo podrías pasar así sin ningún tipo de problema.
De hecho, lo vamos a dejar así para que veamos que funciona, ¿vale?
Aquí podríamos seleccionar la película.
Podríamos tener aquí Movie, Await, Connect...
Bueno, vamos a llamarle Movies, ¿vale?
Y aquí tendríamos el Select del título, no sé qué, no sé cuánto.
Y le ponemos el From Movie, Where UID to Bin y aquí le pasamos nuestro UID, ¿vale?
Y aquí ya tendríamos el Movies, Movies 0.
Así que la misma película que hemos creado ya la podríamos tener.
Este resultado no lo necesitamos.
De hecho, esto habría que hacerlo en un Try Catch, ya sabéis, porque es importante.
Y además, al hacer un Try Catch aquí, es importante que aquí este error nunca permitáis que lo vea el usuario ni nada, ¿vale?
Porque aquí puede enviarle información sensible.
Estoy seguro que alguna vez habéis visto...
Os voy a enseñar esto porque esto es bastante este, este tipo de cosas, ¿no?
De que el usuario está utilizando tu página web, ¿vale?
Revienta por lo que sea y entonces le aparece todo esto, ¿no?
Le aparece...
Ha habido un error y le aparece todo esto.
Y bueno, peor es que he visto de que le digan tokens, no sé qué, estado...
Bueno, esto siempre hay que evitarlo, obviamente.
Y también siempre que podáis, pues evitáis también el hacerlo...
O sea, ya en PHP, por supuesto, ¿no?
Pero PHP es que tiene muchos peligros.
Pero también el hecho de mandarlo en la consola, que tengáis en cuenta que a lo mejor no tiene tanto sentido mandarlo a la consola,
sino que lo podéis enviar a un servicio para verlo más adelante.
Entonces, bueno, puede enviar información sensible.
Así que aquí a lo mejor lo que puedes hacer es un throw new error dependiendo del error.
Error create a movie.
Y entonces esto, enviar la traza a un servicio interno, que sea, yo qué sé, send, log, lo que sea, ¿vale?
Esto ya lo podéis hacer.
Con esto ya podríamos crear nuestra película, ¿vale?
Vamos a ver si funciona.
Parece que sí que funciona y además aquí nos ha creado la idea perfectamente.
Así que funcionar funciona.
Ya tenemos esto y os dejo como ejercicios este, que es facilito, ¿vale?
Ejercicio crear el delete, ¿vale?
Esto fácil.
Ejercicio crear el update, este también es fácil.
Yo creo que lo más difícil aquí quedaría to do, crear la conexión de genre.
Este sería un poco más difícil, ¿vale?
Pero estos ejercicios, estos dos serían bastante fáciles.
Vamos a hablar de inyección de dependencias, que es un patrón de diseño que se utiliza en programación
para aumentar la eficiencia y la modularidad de tu código, ¿vale?
La idea básica detrás de la inyección de dependencias es normalmente que un objeto, una clase o incluso una función
recibe sus dependencias desde fuera, ¿vale?
Se le inyectan.
O sea, desde fuera se le pasan.
Y el comportamiento interno cambia dependiendo de cómo se le pasa esta información.
Y esto, claro, es brutal porque te facilita el control, reutilización y probar el código, ¿vale?
Desacoplas el código, súper importante, porque así ese objeto o esa clase funciona de diferentes maneras,
depende de lo que le llegue desde fuera.
Y eso está muy bien, sin necesidad de tocar la clase, que es algo parecido, ¿no?
A lo que hemos hecho aquí.
Si os fijáis en esto, veis que aquí teníamos tres movie model.
Esto es como una inyección de dependencias pirata, ¿vale?
Esto es una inyección de dependencias pirata, porque es verdad que es como una dependencia
que cambia entre que vaya a una base de datos, a otra base de datos, al sistema de memoria,
pero necesitamos modificar el fichero, ¿no?
Necesitamos modificar el fichero.
Es poco porque solo es una línea de código, que seguro que habéis visto ahí códigos
que tienes que cambiar un montón de cosas.
Solo tienes que cambiar una línea de código y ya es una ventaja,
pero aún así tienes que cambiar código.
Y esto es lo que queremos evitar con la inyección de dependencias, ¿vale?
Lo segundo, bueno, que puedes a la hora de inyectar la dependencia,
lo que sea desde fuera, también te mejora el hecho de poder testear tu código.
Y esto lo veremos.
La tercera, la reutilización.
Y lo cuarto, el control, ¿no?
Porque te facilita, por ejemplo, aquí nos facilita un montón el hecho de,
oye, si quiero cambiar cualquier cosa de lo de MySQL, ¿vale?
No tengo que ir aquí.
O sea, no tengo que tocar nada de aquí.
Tengo que ir al modelo y cambiarlo.
Que justamente es lo que hemos estado haciendo.
Y que ha funcionado brutal, ¿verdad?
Que ha funcionado súper bien.
Bueno, pues esa es la ventaja que tenemos.
Vamos a ver cómo podemos traernos la inyección de dependencias aquí
y vas a ver que tiene todo, todo el sentido del mundo hacerlo, ¿vale?
Entonces, fíjate que aquí teníamos aquí los modelos.
Muy bien.
Estos modelos que teníamos aquí a saco, a saco, ¿ok?
Vamos a hacer una cosa.
¿Veis que teníamos aquí una clase?
Que era Movie Controller.
Muy bien.
Esta clase que tenemos aquí, vamos a hacer algo.
En lugar de tener los métodos estáticos, vamos a cambiar los métodos estáticos, ¿vale?
Los quitamos.
Estáticos significa que puedes utilizarlos sin necesidad de crear una instancia de la clase, ¿vale?
Pues todos estos, joder, ya lo he hecho, ¿vale?
Todos estos métodos estáticos, ¡pum!
Fuera.
Los quitamos.
Y ahora lo que vamos a hacer también, vamos a, en las async, los asyncs, los vamos a quitar.
Vamos a transformar esto en una Arrow Function, ¿vale?
Lo hacemos con todas, Arrow Function, porque esta clase ahora vamos a hacer que tenga que crear una instancia
y vais a ver por qué va a ser importante, ¿vale?
Hacemos que todo sea Async Await.
Ya sabéis que podéis utilizar también Arrow Functions, así que, nada, creamos cada una con una Arrow Function.
¿Por qué hago Arrow Function?
Bueno, porque dentro de estos métodos vamos a utilizar ahora, vamos a utilizar this, o sea, vamos a utilizar this,
pero es muy sencillo, no tiene nada que ver con el this complicado, ¿vale?
Entonces, ¿ves?
Lo pasamos a Arrow Function.
Hasta aquí, bien, ¿no?
Que no se me olvida la async, ¿vale?
Ahora le vamos a añadir un constructor.
Y en el constructor le vamos a decir que el movimodel le llega por parámetro.
Vamos a hacer this.movimodel, movimodel, ya está, ¿vale?
Ahora, todos los movimodel que habíamos visto aquí, estos los quitamos de aquí, ¿vale?
Los quitamos de aquí y lo que hacemos, esto es que a mí me dice que no los encuentra, que no están definidos,
lo que vamos a hacer es todos estos los vamos a cambiar por this.movimodel.
¿Qué quiere decir lo que hemos hecho?
Lo que hemos hecho ahora, básicamente, es que esta clase vamos a tener que crearla con el new,
o sea, vamos a tener que hacer const movicontroller igual new movicontroller y le vamos a tener que pasar como parámetro
qué modelo es el que tiene que utilizar, ¿vale?
qué modelo es el que quiere utilizar, pero esto lo vamos a hacer desde fuera,
porque así justamente lo que estamos haciendo es evitar que sepa el controlador qué es lo que está utilizando.
Ahora mismo es totalmente transparente, es una cosa que no tiene ni idea, no lo va a saber aquí.
Es totalmente agnóstico si va a utilizar una cosa u otra.
Ahora simplemente sabe que aquí el this tiene el movimodel y esto lo puede utilizar y ya está.
Para esto, ahora, ¿dónde estábamos utilizando el movicontroller?
Pues damos un paso y lo buscamos.
¿Dónde era? Pues aquí en rutas.
En las rutas, fijaos que utilizamos aquí el movicontroller y lo tenemos aquí como si nada.
Pues aquí lo que podemos hacer es decir, bueno, este movicontroller que lo utilizaba aquí como si nada,
en realidad voy a crear aquí el movicontroller utilizando new movicontroller y aquí le vamos a pasar movimodel
y aquí es donde podríamos decidir, aunque verás que este no es el punto donde lo vamos a hacer,
pero este podría ser el punto donde lo podríamos decidir.
Aquí podríamos traernos el movimodel, ¿vale?
movimodel del, por ejemplo, vamos a utilizar otra vez el de modelos, el de MySQL, por ejemplo, ¿vale?
movi.js, porque tiene sentido que sea el de movimodel, el de MySQL, que es el que hemos hecho.
Ahora, este movicontroller es en realidad el que utilizaríamos aquí.
Fíjate la diferencia, ¿vale?
Ahora estamos creando la instancia de cada una de estas.
La estamos haciendo aquí, pero tampoco lo vamos a hacer aquí.
Luego verás por qué no lo vamos a hacer aquí.
Entonces, ahora, fíjate que cambiamos este controlador para que se le pueda pasar el modelo desde fuera.
Ahora aquí no tiene ni idea.
Y es aquí, en este punto, que creamos la instancia y le pasamos el movimodel, el movimodel.
Vale, pues ahora aquí en la API vamos a ver si esto sigue funcionando.
Vale, sigue funcionando correctamente.
Esto todavía nos lo vamos a llevar un paso más allá, ¿vale?
Porque tampoco en las rutas es el sitio correcto en el que deberíamos saber cuál es el modelo que queremos hacer.
Así que esto lo que vamos a hacer es, este modelo lo quitamos de aquí,
y vamos a volver a crear aquí una función, por ejemplo, para evitar saberlo aquí.
Vamos a envolver todo esto.
Vamos a hacer export const create movimodel, ¿vale?
Aquí también le pasamos el movimodel, ¿vale?
Y esto, todo esto que teníamos aquí, lo pasamos aquí dentro.
En lugar de exportar el movimodel, ¿vale?
Lo vamos a poner aquí.
¿Por qué esto ahora es importante?
¿Por qué esto que estamos haciendo es importante?
Porque, fijaos, ahora lo que hemos conseguido es que este create movimrouter,
en lugar de crear toda la información en el cuerpo de la función,
lo que estamos haciendo es crear una función en la que podemos devolver la creación del router.
Y entonces, ahora, desde el punto de entrada de nuestra aplicación, que es aquí,
¿veis que tenemos aquí el movimrouter?
Este movimrouter ahora no existe, sino que tenemos que crearlo.
Así que hacemos aquí create movimrouter, create movimrouter,
y será aquí que le vamos a decir cuál es el modelo que tiene que utilizar.
Pues el modelo que tiene que utilizar lo vamos a decidir aquí,
que va a ser movimodel, ¿vale?
Modelos, tal.
El de SQL.
Y es desde el punto de entrada, fíjate cómo es, ¿no?
Desde el punto de entrada que estamos creando las rutas.
Al crear las rutas, le pasamos por parámetro al controlador.
¿Qué modelo es el que utiliza?
¿Vale?
Aquí tenemos todos los controladores.
Devolvemos las rutas, que las utilizamos aquí.
Y entonces, el modelo solo lo sabemos desde el punto de entrada.
Vamos a ver si esto funciona.
A ver si no me he equivocado nada.
¿Vale?
Sigue funcionando.
Entonces, ahora, la historia, ¿dónde termina?
La historia termina en que esto lo podemos llevar un paso más allá.
Porque tenemos que inyectar la dependencia desde lo más fuera posible
para poder testear esto.
Entonces, vamos a crear aquí, fíjate.
Vamos a crear aquí también un archivo que sea server.js.
O mejor, podríamos tener como diferentes clientes.
Podríamos tener un servidor server with mysql.js.
¿Vale?
Entonces, este server mysql, lo que vamos a hacer es,
vamos a poner que este app, vamos a poner un export const create app.
Al que le vamos a pasar el movie model también.
¿Vale?
Y este es el que directamente va a crear todo esto.
Este movie model no se lo pasamos aquí y lo que estamos haciendo,
básicamente, es que ahora podríamos tener diferentes server with mysql.
¿Vale?
Importamos aquí el create app desde la app.
¿Vale?
Y ahora podemos importar el modelo de la base de datos,
el de mysql o el que queramos.
Esto es movie model.
¿Vale?
Create app con el movie model, movie model.
Y ahora, ¿qué es lo que tendríamos?
Lo que tendríamos es que ahora podríamos tener un servidor que sea solo con mysql.
Otro que sea con mongo db.
Otro que sea desde memoria.
Lo vamos a ver.
¿Vale?
Fíjate, ahora lo que podríamos tener en el package.json sería, por ejemplo,
tener uno que sea start mysql.
Y esto simplemente es node watch server with mysql.
¿Vale?
Pero también podríamos tener el start local.
Imagínate.
Start local.
Node watch server with local.
¿No?
Esto lo podemos llevar tan lejos como queramos.
Pero lo bueno es que puedes tener ahora, si quisieras,
y esto lo podríamos hacer también como variable de entorno.
¿Vale?
With local.
Local.
Bueno, sí, con with local.
Esto lo podríamos tener aquí.
Y fíjate que lo que estamos haciendo,
aquí vamos a tener el modelo del local file system.
¿Vale?
Y ahora, lo que único que cambia aquí es que lo que estamos haciendo es inyectar
el modelo desde lo más fuera posible para poder cambiar el comportamiento interno.
¿Vale?
Y aquí, pues, lo que podemos hacer es no, no, npm run, npm run, ¿cómo era?
npm run start local.
Y esto, sí, vale.
Hay alguna cosa que no he hecho bien.
No puedo encontrar el modelo útils.
Ah, y esto parece un problema de que algo dejamos aquí a medias, a lo mejor.
Ta, ta, ta, ta, ta.
Read JSON.
A ver, este útils.
Útils.
Sí, esto está mal.
Esto, esto está mal.
Vale.
Vale, ya está.
No sé, estaba mal la, eso es porque seguramente lo movimos en algún momento y tal, ¿no?
Pues, lo que estamos haciendo aquí, fíjate, start local.
Bueno, pues, lo que tenemos ahora es la aplicación en local.
¿Vale?
Esto está tirando de local.
Esto está tirando de local.
¿Vale?
Dices, bueno, ahora quiero la aplicación que sea de MySQL.
Start MySQL.
Y esto ahora estaría tirando de MySQL.
Lo que estamos haciendo con esto es inyectar el modelo desde lo más, lo más lejos.
Y para qué sirve esto, ¿no?
Alguien a lo mejor diría, ¿alguien había visto antes como un curso va de junior a senior?
No, no digáis, esto no es senior, amigos.
Esto no es senior, ¿vale?
¿Por qué?
Porque lo que estamos haciendo, claro, esto lo podrías pasar todos por parámetro.
Esto no es senior.
Esto es pasar por parámetro algo y ya está, ¿vale?
Y ahora la hacemos, la hacemos.
No es senior.
No, J2.
A ver, si sabéis utilizar funciones y por parámetro, esto no es senior.
No es senior.
Porque al final lo que hemos hecho es, uno, utilizar una clase que lo que estamos pasando es por parámetro.
Y senior, al final, esos son más de 5 años o 7 años de experiencia y tal.
Esto al final un junior que puede tener de 0 a 5 años lo puede saber hacer, ¿vale?
Porque si sabéis utilizar funciones, si sabéis utilizar funciones, lo que estamos haciendo aquí es crear todo el rato funciones.
No, de trainee tampoco he dicho.
No he dicho que sea de trainee.
De trainee no, porque trainees están aprendiendo todavía.
Pero lo que hemos hecho aquí es envolver el código en una función y lo que estamos haciendo es inyectar la dependencia que si no te quieres liar, lo que le estoy pasando es un parámetro.
Es que le estás pasando un parámetro.
Le estamos pasando a la aplicación.
Antes la aplicación era así, ¿vale?
Mira, para que lo veamos, el antes y el después.
Entonces, antes, lo que estábamos haciendo era importar el movie model así directamente, ¿no?
Y teníamos todo este código aquí.
Lo único que hemos hecho...
Esto era el antes, ¿no?
El antes.
Importar y teníamos aquí todo el código y lo que hacíamos es utilizar este código y tal.
Lo que hemos hecho simplemente es envolver.
Es envolver en una función para llamar a la función y poder pasarle un parámetro que sea el modelo que realmente utiliza, ¿vale?
Pero esto no deja de ser un parámetro.
No deja de ser un parámetro como lo utilizáis en cualquier función.
Es un manejo de parámetros, lo que muchas veces lo que estamos utilizando le llaman el patrón inyección de dependencias porque no es tanto la complejidad de lo que se hace, que no es complicado, de verdad.
O sea, si lo miramos poco a poco, mira cómo ha funcionado la inyección de dependencias.
Y si no, lo que podéis...
Y os recomiendo es que lo que tenéis que hacer es comparar la clase 4 con la 5.
Pero lo único que tenemos que hacer es envolverlo de una forma que tengamos que pasarle y crear una instancia o ejecutar una función pasándole por parámetro lo que queremos que utilice.
Y se le llama inyección de dependencias no por la dificultad que tenga ni porque sea algo difícil, sino porque lo que se le pasa es una dependencia.
Pero esto podría ser una configuración, un objeto o lo que sea.
Aquí es una función que recibe el movie model.
Entonces, aquí veis, hemos hecho también una función en el router que también le tenga que pasar el movie model porque no hay otra forma de hacerlo así a no ser que tengas que poner el in por a mano.
Pero entonces no funciona ya como una inyección, como si fuese un parámetro y te rompe un montón de esquemas.
Lo mejor de esto es que entonces ahora cuando tengamos los test, cuando tú por lo que sea quieras hacer aquí un test, quieras un test, lo bueno es que esto te va a simplificar un montón la vida.
Porque ahora no vas a tener que hacer ningún mock, no vas a tener que hacer nada raro.
Simplemente podrás importar la aplicación y desde fuera le podrás decir cuál es el modelo que tiene que utilizar.
Y puedes decirle que utilice un modelo que vas a poder testear, que no vaya a una base de datos de real, ¿sabes? Cosas así.
Y lo puedes hacer súper fácil.
Que esa es la clave de la inyección de dependencias, ¿vale?
Esa es, digamos, la razón por la que se hace.
Si vais a hacer un proyecto muy pequeño, muy sencillo, seguramente no vais a necesitar nada de esto.
Pero si realmente vais a trabajar en una empresa, vais a ver que hay veces que se utilizan estos patrones de diseño.
Porque es muy fácil que el día de mañana estén utilizando MongoDB y entonces de repente se pasen a otra.
O están utilizando MongoDB y se pasan a una nueva versión de la base de datos donde han cambiado colecciones y tal.
Y hay dos modelos que los dos son de MongoDB, pero funcionan ligeramente diferente.
Este tipo de cosas pasan un montón en las empresas y entonces por eso es interesante que lo sepáis, ¿vale?
Y yo que sé, este tipo de cosas no se enseñan, ¿sabes?
El otro día me decía alguien, me decía, es que siempre haces un Hello World, no sé qué.
Pues esto no es un Hello World, esto es la vida real.
Vamos con el tema interesante, el despliegue de nuestra base de datos.
Así que vamos a utilizar un servicio que es bastante complicado.
Vamos aquí a PlanetScale, ¿vale?
PlanetScale es un servicio que está brutal y que lo que tenemos es la posibilidad de crear bases de datos totalmente gratis.
Mira, yo he creado una antes, pero la voy a eliminar, ¿vale?
La voy a eliminar para que la hagamos desde cero.
Delete.
Y así lo hacemos desde cero.
Delete Database.
¿Vale?
Vale.
Entonces, tenemos aquí Start with an Entity Database o Import from an Existing Database.
Pero tiene que ser una que exista, que sea disponible por internet, ¿vale?
Pero no la tenemos disponible en internet.
Así que vamos a empezar con una en vacío, ¿ok?
Create New Database.
Ahora, vamos a ponerle aquí Movies Database.
Y en la región podéis utilizar el que queráis.
Vamos a decir, yo qué sé, Frankfurt, que a mí me pilla cerca.
Importante, vamos a poner el Hobby, ¿vale?
Que si no te cuesta 47 dólares.
Y la verdad es que la de Hobby es bastante, bastante, bastante.
Es gratis y es bastante que te permite hacer un montón de cosas.
Como, joder, ahora no me sale la palabra.
¿Cómo es la palabra?
Ah, no me sale la palabra.
Qué rabia.
Generosa.
Gracias, Nabil.
Gracias.
¡Qué rabia!
Generosa.
Es muy generosa.
Tenéis mil millones de lecturas y diez millones de escrituras.
Está brutal, ¿eh?
Es muy generosa.
Entonces, hay una cosa mala y es que ahora pide tarjeta de crédito.
Pero no te cobran nada a no ser que te pases, que ya sería raro, ¿vale?
Entonces, aquí en Hobby le vamos a Create Database.
¿Ok?
Aquí hay diferentes formas.
Una sería la de Node.
Y no está mal.
Le podéis dar a Node.
Le podéis dar aquí Password Name, porque primero te da un nombre de password, ¿vale?
Te genera el nombre.
Esto no es el password, ¿vale?
Este es el nombre, el nombre del password, ¿vale?
No es el password.
Y tenéis diferentes formas de utilizarlo.
Por ejemplo, en Django, en Go, en Java, PHP.
O sea, lo podéis utilizar en un montón de sitios.
Nosotros vamos a poner Node.
Le voy a dar a Create Password, que ahora sí sale el password, ¿vale?
Entonces, lo voy a que no se vea.
Os voy a enseñar un momento esto sin que se vea nada, ¿vale?
Porque justo te sale aquí un poquito la información de cómo tienes que hacer.
No confías en nosotros, hombre, varón.
No.
No.
Bueno, entonces, aquí teníais, tendríais un poco como lo que hay que hacer, ¿no?
Instalar MSQL2, que es justamente lo que teníamos, y instalar .env.
Vamos a instalar .env, ¿vale?
Porque justo lo vamos a necesitar para que nos lea la variable de entorno.
Así que instalamos .env, menos e.
Vale.
Voy a volver a poner la cámara esta, porque ahora me sale el archivo .env,
que os pone el archivo .env, que lo único que hay que hacer es copiarlo y ya está, ¿vale?
O sea, es poner el .env, lo copiáis tal cual, y ahí tiene el connection string, que se le llama,
donde sale todo el password, toda la forma de conectarse y todo, ¿vale?
Y luego, justamente, ya os da un poco la información de cómo tendríais que hacer el código.
Que, bueno, el código ya lo hemos visto juntos, o sea, que tampoco hace falta que hagáis nada.
No es un 2, 3, 4, ¿eh?
No os preocupéis.
Pero, bueno, lo importante es que ya tenemos tanto el connection string y todo.
Lo tenéis que copiar en el .env, lo tendríais y ya está.
Ahora, voy a no liarla, ¿vale?
¿Veis? Está aquí el .env, está aquí, ¿vale?
Con el connection string.
Así que nos vamos al modelo este, aquí.
Y ahora, todo esto que habíamos hecho aquí, a ver, pues no es tan necesario.
De hecho, podemos hacer una cosa.
Una cosa que podemos hacer es crear esto como si fuese un connection string.
O podríamos poner local o default config, default config si queréis, mira, default config, default config.
Y podríamos poner aquí que el connection, perdón, connection, sea el process.env, punto, a ver si me acuerdo cómo era, ¿vale?
Este, database, URL, no sé qué.
Y si no, por defecto, le ponemos el default config, ¿vale?
Connection string y este connection string lo conectamos aquí, ¿vale?
Con esto ya tendríamos la conexión.
Y esto, hombre, funcionar, funcionaría, ¿ok?
Pues con esto ya tendríamos la conexión a MySQL.
Vamos a levantar esto.
Parece que la conexión sí que la hace.
Pero, obviamente, si vamos aquí y hacemos la request, ¿vale?
Pues me ha dejado fatal.
Me ha dejado fatal, pero esto es porque...
A ver si la estamos liando aquí.
Pero esto, getAll, a ver si en algún punto se me ha olvidado...
No, sí que lo está detectando esto.
O sea que en el API este, ¿ves?
GetAll, o sea, sí que lo están contando correctamente.
Lo que no estoy haciendo es el .env, ¿no?
O sea, a lo mejor es eso.
Se me ha olvidado el import.envconfig, ¿vale?
Es esto.
Me faltaba esto para cargar la variable de entorno.
Gracias, que me lo habéis dicho por ahí en el chat.
Vale, ahora sí que si vamos aquí me debería petar o algo, ¿ves?
Me está petando.
Básicamente porque...
A ver si encontramos...
No encuentra la tabla, ¿vale?
No encuentra la tabla.
No pasa nada.
Lo que vamos a hacer ahora es conectarnos con PlanetScale.
Hay diferentes formas de instalar el cliente, ¿eh?
Que dependiendo del sistema operativo y tal, lo tenéis que mirar.
Por ejemplo, aquí están las instrucciones de Macos, pero tenéis las instrucciones de Linux, de Windows y de todo.
O sea, que no os preocupéis.
También lo tenéis por manual, cosa que no recomiendo.
Pero yo voy a utilizar las de Macos.
Yo tengo Brew, que es una forma de instalar este tipo de paquetes de líneas de comandos y tal.
Así que hay que hacer un Brew Install de esto de aquí.
Hacemos aquí el Brew Install.
Y esto te va a instalar la línea de comandos de PlanetScale que la necesitamos para iniciar sesión y todo esto, ¿vale?
Así que nada, le vamos a dar por aquí.
Ahora en un momentito termina.
Creo, y esto es importante, que también te pide el cliente de MySQL si no lo tenéis.
Yo se supone que lo tengo, pero igualmente lo voy a instalar por si acaso.
Pero yo se supone que lo tengo, ¿vale?
Así que vamos a poner por aquí, hace el fetch, ¿vale?
Y bueno, el update, esto sería solo para actualizar, no para hacer nada más.
A partir de aquí, a ver, el kickstart, vamos a poner el kickstart, create database, bla, bla, bla.
¿Vale?
Aquí, este Getting Started PlanetScale Click.
Este, el que vamos a seguir, que es un momentito.
Lo primero, hay que iniciar sesión, ¿vale?
Bueno, joder, esto todavía está instalando.
Bueno, lo primero que hay que hacer es iniciar sesión.
¿Por qué?
Porque vas a iniciar sesión desde la línea de comandos y esto va a crear un nexo con la página de PlanetScale, ¿vale?
Y así, desde tu línea de comandos, podrás entrar en tu base de datos que tienes en producción y así podrás, pues, insertar tablas y todo esto.
Así que lo vamos a hacer en un momento.
En PlanetScale se pueden hacer relaciones.
No se pueden hacer joins, pero sí que tienen como una documentación que te explican la forma de hacer joins, porque si no es un poco rollo.
Pero es que lo hacen porque es súper rápido.
O sea, está pensado para que lo hagas más en el código que no lo hagas en MySQL.
Que a veces tiene sentido.
Yo no veo tanto problema, la verdad, que hay mucha gente que eso le molesta.
Pero hay veces que el join, sinceramente, es algo que también puedes hacer en base a código y recorriendo con maps, joins y tal, lo puedes solucionar sin ningún tipo de problema.
Y si no, hay algunos ORMs que te facilitan el trabajo y así no te tienes que preocupar de nada.
Esto, por cierto, me está instalando aquí hasta Python.
O sea, he instalado MySQL Client y me está instalando aquí Python y la madre que lo parió.
Ah, mira, gracias, hombre.
Gracias.
Bueno, vamos a poner PSScaleOutLogin.
Aquí sale el código este, que es el mismo código que tenéis aquí.
No pasa nada.
Es un código que aparece en un momento.
O sea, que no pasa nada que lo veáis.
No os preocupéis.
No es más ineficiente hacerlo con map.
Sí que es más ineficiente, normalmente.
Sí que es más ineficiente.
¿Ves?
Ya hemos iniciado sesión aquí, así que perfecto.
Sí que es más ineficiente.
No es lo recomendado.
Pero hay veces que este tipo de base de datos, que están pensadas más para serverless, evitan los joins por un tema de rendimiento por su parte y de escalabilidad.
Pero igualmente es que van muy rápido.
Es que realmente son bases de datos que están muy optimizadas y que se quitan ese tipo de funcionalidad para darte como fuerza bruta muy bestia.
Así que por eso lo hacen, ¿vale?
Porque el join normalmente es una cosa muy costosa.
Y lo que hacen es, bueno, quitamos el join y optimizamos lo que son las consultas simples.
Y así, pues vas a tener un montón de potencia y los joins los haces de tu parte, ¿vale?
Por eso lo hacen, básicamente.
Entonces, vale, shell.
Vale, vamos a crear aquí el shell.
Hacemos, pese a que el shell, shell sería para empezar con la línea de comandos, ¿vale?
Y luego aquí le tenemos que decir el nombre de la base de datos.
MoviesDB, ¿vale?
MoviesDB, así que MoviesDB.
Y luego tendríamos el main.
¿Por qué main?
Pues porque en PlanetScale, ¿ves?
Cuando vamos a nuestra base de datos, una cosa muy interesante que tiene, que esto lo veremos más adelante, es que tiene ramas.
O sea, tú puedes hacer, básicamente, puedes tener la rama principal, ¿vale?
Pero puedes empezar a crear ramas por si tienes una nueva versión de tu base de datos, puedes sincronizar ramas.
Es bastante potente, es bastante increíble, ¿vale?
No lo vamos a ver hoy, obviamente.
Nos vamos a quedar con la rama principal, pero podéis hacer un montón de cosas, ¿vale?
O sea, podéis tener ahí un montón de ramas para tener más de una versión de la base de datos.
Así que en este caso, vamos con el main.
Y aquí, cuando entremos en el Shell, ¿veis?
Ahora nos pone aquí el Shell.
Aquí, ahora sí, podríamos pegarle todo lo que hemos hecho aquí.
Fijaos todo lo que habíamos hecho aquí.
Vamos a dejar hasta...
Esto es que, claro, esto no sé si...
El Insert funcionaba, creo.
Vale, vale.
Si el Insert funcionaba, vamos a hacer hasta aquí.
¿Vale?
Y las películas, pues las insertamos ahora a mano.
Creo que funcionará pegando.
¿Vale?
Se ha ejecutado todo lo que teníamos, ¿vale?
Todo lo que teníamos se ha ejecutado.
Perfecto.
Si nos vamos aquí, de hecho, a Insights, creo, deberíamos ver...
¿Veis este pico?
Este pico es porque ha detectado todos los inserts que ha hecho.
Y fijaos que está súper chulo porque además te dice cuánto tiempo ha tardado.
Esto está súper bien porque te da un montón, pero un montón de información
de cuánto te tardan las tablas, los selects, los inserts.
Y así muchas veces lo que haces es que puedes optimizar,
puedes ordenar de cuál es el más lento, el más rápido.
O sea, es brutal, ¿vale?
Con esto que hemos hecho ya y el Connection String,
si volvemos a nuestro proyecto y le damos aquí, bueno, pues...
Ah, tenemos que levantar aquí esto, ¿vale?
Levantamos nuestro proyecto, vamos a mirar el send request, ¿vale?
Nos da vacío, tiene sentido porque la tabla está vacía.
Si creamos la película del Goodfather, ¿vale?
Este, le damos aquí, se ha creado, parece que correctamente.
Así que si ahora queremos recuperar todas las películas, ¿veis?
Esto ya lo tenemos totalmente en producción y funcionando.
Y nada, hemos tardado, pues, un momento.
De hecho, este, creo que sí que hemos hecho Standpoint, ¿vale?
Pues este también está funcionando.
Así que, amigos, hemos hecho conexión a base de datos, The Note.
Hemos aprendido inyección de dependencias,
temas que muchas veces me dicen, no, que hola mundo.
Pues toma hola mundo.
Y hemos hecho despliegue a producción de nuestra base de datos en PlanetScale.
Casi nada, ¿eh? Casi nada.