En la primera parte de este artículo hablamos sobre NestJS dando un repaso a sus principales características que han hecho de él uno de los frameworks que más están creciendo en uso y popularidad.
Además de esto, vimos un ejemplo con el que empezar a modelar y construir API usando NestJS sobre una base de datos Mysql. En esta segunda parte, vamos a profundizar un poco más en ese sentido. Ampliaremos nuestro modelo de datos con tablas relacionadas y programando APIS que consulten estas tablas.
Relaciones OneToOne
Para ver este ejemplo vamos a añadir un estado a nuestra tabla task, que estará almacenado en una tabla distinta (por ejemplo task_states). Se trata de una relación OneToOne porque un registro de la tabla task solo contiene una instancia de task_states.
En primer lugar, tenemos que definir y crea la tabla taskStates. Para ello, dentro del directorio /task creamos el archivo task-states.entity.ts de esta forma:
Al volver a arrancar nuestro servidor la tabla task_states, podremos insertar los estados que creemos necesarios en este caso yo he insertado dos:
insert into tasks_db.task_states values (null, ‘pending’); insert into tasks_db.task_states values (null, ‘done’);
En este punto, ya podemos indicar la relación en la tabla task, para ello nos vamos al archivo task.entity.ts, importamos la nueva entidad y definimos la relación de esta forma:
Esto creará el campo stateId en nuestra tabla task y ya podremos añadirlo en la query que hagamos sobre este modelo. Por ejemplo en el GET:
Si en este momento le damos un valor al campo stateId de los registros que tengamos en nuestra tabla, el GET sobre tasks debe darnos el siguiente resultado:
Relaciones OneToMany
Una relación OneToMany se da cuando la tabla A contiene múltiples instancias de la tabla B. Para ver este ejemplo hemos creado una nueva tabla User que contiene varios usuarios. Vamos a implementar una reacción en la que un task puede tener varios users asignados.
Para ello debemos modificar ambas entidades, por un lado indicamos en un task puede tener varios usuarios asignados modificando el archivo task.entity.ts de la siguiente forma:
Por otro lado, en la entidad user debemos indicar que un usuario va a poder estar asignado a muchas tareas. Esto lo haremos con una relación ManyToOne modificando el archivo user.entity.ts:
En este momento ya podemos añadir el cruce con estas tablas en los repositorios de queries para poder recuperar los datos de estas relaciones. Por ejemplo, en task.repositoy.ts cuando hagamos un GET sobre todas las tareas podemos cruzar las tablas de esta forma:
Al ejecutar ahora el GET que devuelve todas las tareas, esta será la respuesta:
También podemos añadir el cruce en nuestra tabla usuarios para conocer las tareas que cada uno tiene asignadas:
Y este sería el resultado al hacer un GET sobre los usuarios:
Relaciones ManyToMany
Una relación ManyToMany se da cuando la tabla A contiene varias instancias de la tabla B y a su vez la tabla B contiene múltiples instancias de A.
Este tipo de relación es un poco peculiar ya que para poder implementarla, a nivel de modelo necesitaremos una tabla intermedia que sea capaz de establecer las relaciones.
Imaginemos que queremos tipificar la naturaleza de las tareas de modo que una tarea puede ser de varios tipos y un tipo de tarea puede tener muchas de estas asociadas.
En primer lugar, hemos creado la entidad Type y hemos creado varios registros en esta entidad. Para establecer una relación entre task y type debemos indicarlo en el archivo task.entity.ts de la siguiente forma:
Si observamos, el decorador @joinTable() creara una nueva tabla en nuestro modelo de datos (task_types_type) donde se almacenarán las relaciones entre ambas tablas. A partir de este momento podemos establecer la relación en la query que se realiza en el GET de tasks:
De esta forma, cuando hagamos un GET de task, recuperaremos también todos los tipos a los que pertenecen:
Esta relación pude definirse de forma inversa de forma que al consultar los tipos podamos obtener todas las tareas que tienen ese tipo asignado.
Conclusiones de NestJS
NestJS junto con TypeORM se ha convertido en un potente framework que nos permite crear APIS y modelar nuestra base de datos de forma rápida, ordenada y escalable. Los ejemplos que hemos visto aquí hacen referencia sobre todo a la rescuperación de datos, pero NestJS nos da también múltiples herramientas para la modificación y creación de datos en todo estos tipos de relaciones.
El código con los ejemplos de este artículo más el de la primera parte está en este repositorio.