API with NestJS #151. Implementing many-to-one relationships with Drizzle ORM

NestJS SQL

This entry is part 151 of 168 in the API with NestJS

Managing relationships between tables is a significant part of dealing with SQL databases. In this article, we continue learning to use Drizzle ORM with NestJS and implement many-to-one relationships.

Check out this repository if you want to see the full code from this article.

The many-to-one relationship

With many-to-one relationships, a row from the first table can be connected to multiple rows in the second table. What’s crucial is that the row from the second table can relate to just one row from the first table.

A great example is an article that can have a single author. On the other hand, a user can be an author of multiple articles. To implement that, we need to store the author’s ID in the table. This way, the will act as a foreign key and match rows from the table.

 

When defining a foreign key, PostgreSQL creates a foreign key constraint to ensure our database stays consistent. This prevents us from having an value that points to a user that does not exist. This means that we can’t:

  • delete a user that’s an author of an article
    • first, we would have to delete the article or change its author
    • alternatively, we could use the option in PostgreSQL to delete all articles the user is an author of
  • create an article with the that does not point to a valid user
  • update existing articles and change the to point to a user that does not exist

Creating a many-to-one relationship with the Drizzle ORM

In one of the previous parts of this series, we created the basics of the and tables. Let’s add the column to our schema.

database-schema.ts

Now, we can use the Drizzle ORM Kit to create a migration file.

Check out API with NestJS #149. Introduction to the Drizzle ORM with PostgreSQL to learn more about managing migrations with the Drizzle ORM Kit

When we run the above command, Drizzle creates a SQL migration file.

0002_add-author-id.sql

The last step is to run the migration.

There is one crucial thing to consider here. The new column we added is not nullable. If we already have some articles in our database, adding a new non-nullable column without a default value will cause an error. If that’s the case for you, you can create a default user in your database and provide their ID as the value for the in the existing articles.

One-to-one vs many-to-one

In the previous article, we created a one-to-one relationship.

database-schema.ts

To ensure that a particular address belongs to only one user, we added the unique constraint.

However, when adding the column, we don’t include the unique constraint. This allows multiple articles to have the same author.

Creating an article with an author

When creating articles, we should provide the author’s ID.

articles.service.ts

What’s important is that we shouldn’t expect the author’s ID to be provided directly in the body of the POST request. Instead, we should get this data by decoding the JWT authentication token.

To learn more JWT tokens and authentication, check out API with NestJS #3. Authenticating users with bcrypt, Passport, JWT, and cookies

articles.controller.ts

The type extends the type from Express.

request-with-user.interface.ts

Combining the article’s data and the author

Right now, when we fetch the details of a particular article, we only get the author’s ID.

Let’s change it to send the author’s details.

Making a join query

One solution would be to do a join query. In SQL databases, joins are used to combine rows from two or more tables.

The most basic type of join is the inner join, which returns records with matching rows in both tables. Since each article has an author, an inner join is a valid approach.

articles.service.ts

We also need to use the method in our controller.

articles.controller.ts

With this approach, we respond with the data of an article combined with the details of its author.

Using the Query API

Alternatively, we can use the Query API built into the Drizzle ORM to avoid doing the join query manually. To do that, we need to provide Drizzle with more details about the relationship between the users and articles.

database-schema.ts

Thanks to creating the we can now use the Query API to fetch articles and their authors.

articles.service.ts

We can take it further and fetch both the author and their address.

articles.service.ts

Under the hood, Drizzle ORM will make two join queries—one to retrieve the user and the other to retrieve their address.

Summary

In this article, we’ve explained the many-to-one relationship and implemented it using the Drizzle ORM and NestJS. When doing that, we learned how to combine data from two tables through SQL join queries and by using the Query API built into the Drizzle ORM.

We still have more to learn about relationships with PostgreSQL and Drizzle ORM, so stay tuned!

Series Navigation<< API with NestJS #150. One-to-one relationships with the Drizzle ORMAPI with NestJS #152. SQL constraints with the Drizzle ORM >>
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments