NestJS + Prisma Deep Dive

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone today we're going to take a look at using Prisma with nestjs Prisma is an open source om for node.js and typescript so it's an alternative to writing plain SQL or using any other database access tool like typm and SQL eyes it's a very popular library and for good reason we're going to do a deep dive today and take a look how we can set up Prisma with nestjs to interact with our SQL database but we're also going to take a deeper dive and take a look at many of the features that makes Prisma great including the Prisma client which allows us to autogenerate types and have a type safe query builder for our application Prisma migrate which is a built-in migration system and finally we'll take a deep dive into the Prisma schema to look at one to one one to many and many to many relations as well as look at how we can build relational query Series in our application to stitch together our data in a performant way that's super easy to work with let's jump right in and see how we can work with nestjs and Prisma so to get started we're going to use the nest CLI to initialize a new project if you don't have the nest CLI installed or you want to make sure you're using the latest version simply run pseudo npm install DG for Global at nestjs SL CLI at latest to get the latest version with the nest CLI installed let's initialize a new project by running Nest new and then calling the project whatever you'd like in this case I'll call it nestjs Prisma now you can use whichever package manager you would like in this example I'll use pnpm so with our project created we can CD into the newly created project project folder and I'll go ahead and run pnpm start Dev to start up our Dev server now I'll go ahead and open up this directory in a code editor all right so I've opened up the app in vs code and we can see we have the default nestjs application with our main.ts file which has the bootstrap function to start up our application by calling the nest Factory to create our app module and then we open up the HTTP server by calling app. listen and provide the port we want to listen on for HTTP traffic in this case Port 3000 so if we look at the app module we're creating we simply have an app controller and an app service the app controller is the single entry point into the app right now where we have a get route that will simply return from the app service a stub dummy text string hello world so to make sure app is running okay let's go ahead and open up Postman so we can send a request at it all right so I'm in Postman and I'll launch a get request at HTTP Local Host 3000 and if we send this request off you can see we get the hello world string sent back to us with a 200 status code which means that our server is up and running okay so next up we need to install some new dependencies to work with Prisma so I'll open up a new ter window where we can use pnpm to install the Prisma package and we're going to save this as a development dependency because we're simply going to use this to actually initialize Prisma and get our schema generated so with Prisma installed as a Dev dependency let's go ahead and use it to initialize our Prisma application to do this we'll run pnpm Prisma Enit so now you can see that our Prisma schema was generated in this new Prisma folder additionally it's also created a m for us where it has set a new database URL with the default connection string to a postgress database in this case and then we can see a number of next steps that it wants us to take to get started so we'll go ahead and Implement these so let's go ahead and close close the terminal so besides thism with a database URL created we have the Prisma folder and inside of it we have the all important schema. Prisma file so this Prisma schema file is the main configuration file for our Prisma setup it consists of three main parts so the first of which is going to be the data source so the data source that we can see here it specifies the detail details of the data sources Prisma should connect to so in this case it's simply the connection details to the database we can see we have a provider here and Prisma supports a number of database providers like MySQL postgress mongodb and many more so this is where you specify which database provider you're going to connect to and then secondly we have the URL to actually connect to the database so in this case we can actually take advant of the M function to read the database URL from a m file and of course this is the same M file that it has created for us and populated this database URL string so it's simply reading this in to connect to a database next up we have generators which specify what clients should be generated based on the data model in this schema so in this case you can see we have a provider called Prisma client JF s and this is the provider that we're using in our client application we're going to be utilizing Prisma client JS in our node app so Prisma is actually going to be able to generate types in our application code based off of the schema in this file and provide it to this Prisma client JS provider which is going to cut down on a lot of boil plate code for us and make developing a breeze now the final section is the actual data model definition which specifies our application models or the shape of our data and its relation so the data model is going to consist of the actual entities in our application which will correspond to tables in the database and of course the fields on those entities will match up with columns on the database table so let's go ahead and get started by creating our data model definitions now finally before we get started you'll notice that I actually have syntax highlighting for this Prisma schema and that's because I have the extension installed on vs code called Prisma so if you'd like syntax highlighting formatting and autoc completion for this Prisma file make sure that you look for the Prisma extension in vs code and go ahead and install it so let's go ahead and get started writing our first model so to do this we'll have the model definition which we can see here represents the entity of our application domain so we have the model and we're going to go ahead and call this a product so we're going to be building a virtual store with products so the first field I want to configure is the unique identifier for this entity in this case we'll call it the ID and this will be an integer now I also want to assign a default value for the ID so that it auto increments for every new entity that is inserted into our application so to do this we can take advantage of one of these numerous functions that Prisma provides in this case we'll use the default and then we can provide the autoincrement function to autoincrement this ID finally we'll go ahead and assign the at ID to mark this as the single field ID on the model which also specifies this field as being the primary key in the database next up let's go ahead and Define a name proper property for our product of type string and I also want this to be a unique value so let's say we can't have duplicate products in our system so we can use the at unique constraint to make this unique so an error will be thrown if a duplicate product exists because a unique index will automatically be applied to this field next up let's use a created app property which will be a type date time which will just be a timestamp in the database and we can also take advantage of the default and provide the Now function to set a timestamp of the time when this record was created so that we always know at what time this record was created we can go ahead and do something similar for an updated app property which will also be a date time and we can take advantage of the updated at to auto automatically store the time when this record was last updated so let's go ahead and continue and Define a price for a product this I want to be a floating Point number so we'll have the float type next up let's use a Boolean so to do this I'll have a sale property which will specify whether or not this product is currently on sale so let's go ahead and Mark this as a Boolean which is a true or false value and then we can take advantage of the default parameter and provide false as the default value here so that when this is inserted in the database if it's not already provided then we can say that it will be false by default next up I want to show you how we can use enums in this schema file so Prisma supports enums out of the box and let's go ahead and create a new one so I'll have an enum called availability and inside this en will have two choices one for in store and another one for online so whether or not this product is available in store or online will be one of the two choices here and then we can reference the type in our model so we have this availability field of type availability so we have all the properties we want on the product right now later on we're going to add some relationships to this product and build out some additional entities that the product can reference for now let's keep it simple and show how we can generate some migrations based off of this schema and generate client code that our application can start utilizing all right next up let's make sure that we have a SQL database running locally that we can connect to in our application so in order to do this we're going to run a SQL Docker image on our machine that we can connect to so let's go ahead and create a new Docker composed. yo file and of course make sure you have Docker actually running on your machine if you don't I'll leave a link in the description so you can get started on Docker desktop for your machine so let's go ahead and Define the Manifest that tells Docker what services to actually run so to start off we'll have the services key and then provide the first of service that we're going to call my SQL so this is the name that that we're creating and for this service we need to specify the image that we're going to use so this image will by default look at the dockerhub repository and on there there is a default MySQL image that we will just use for this demonstration next up we can also provide the image with environment variables now we can specify them directly in the Manifest here or we can use the M file key to specify an environment file that will read in the environment variables directly so let's go ahead and do this and reference ourm next up we have the ports which are going to be the ports that we're going to map on our local machine to this running container so that we can send requests to it so by default my SQL we're on on Port 3306 and then we want to map that to our machine's Port of 3306 so we can connect the database based on the local host address so now that we have our MySQL service all set up let's go to the m file where we need to fill in some environment variables that the MySQL image will expect on Startup so the first of these is going to be a mySQL database and this is going to be the database that MySQL will create and connect to by default so in our case let's go ahead and call it nestjs unor Prisma and then secondly we need to specify a root password for the root user that we're going to use so in this case I'll just create a dummy password here so now let's go ahead and start up our MySQL container so I've opened up the project in another terminal window and we can run Docker compose up to start up our MySQL container so you can see here that the server has started and it's listening for connections on Port 3306 so let's go ahead and open up a local database client that we can use to connect to our myql database okay so I've opened up an application called MySQL workbench which is a simple guey that allows us to interact with mySQL databases I'll leave a link in the description where you can download it if you would like to use it on your machine we're going to start off by adding a new MySQL connection you can give this connection name whatever you would like and then for the connection details we want to leave the host name as is as well as the port so this is the local host address where our container is running and then we have the port that we mapped in our Docker compos to the running MySQL container next up we have the root user and then for the password we'll click on store in Keychain and then enter in the password from the M file in this case just the password and then we'll go ahead click okay and double click on the connection so I've gone ahead and successfully connected to our database and you can see we have the default database that was created by default which we specified in ourm you can see of course we have no tables right now because we haven't actually generated any migrations against our schema so let's go ahead and do that next so before we execute our Prisma migration we need to update the database URL that is currently reading in to accurately reflect our new Docker image so let's go ahead and remove this stub postgress database URL and let's add in a new URL for our SQL Server so it's going to look like my SQL colon SL slash and then it's going to be the username of the user we're connecting to so we're going to use the root user and then colon root password so we know the root password is the password down below that we set and then we need to add the host name of the database well we know this will simply be at Local Host so we'll use the Local Host loop back address and then finally the port is 3306 and then we connect to the database name which we know in this case will be nestjs Prisma lastly in our schema up Prisma file make sure to update our provider to a MySQL provider so now that our data source is correctly configured we're ready to execute our first migration against our mySQL database so in essence what this migration is going to do is it's going to synchronize our Prisma schema with our current running database so what this is going to do is it's going to compare the state of our current database and compare it against this schema to determine if there are any changes that need to be applied for example we've introduced new models or entities which will correspond to a new table or if any of the fields on our entities have changed those updates will take place against the database so this allows our schema to always be in line with the current database let's go ahead and execute this Migration by opening up a terminal window now to execute the migration we're going to run pnpm Prisma migrate now we have a few options at this point we can use the Prisma migrate Dev command and what this will allow us to do is to track the changes we make to our database by automatically creating the SQL statements for our migration and saving them in a separate file so this can be really useful When developing locally to view the actual changes that your migrations are making however if you prefer not to generate the SQL you can simply use the push command which will execute the migrations directly without generating any of these SQL migration documents finally there's a migrate deploy command which essentially allows you to apply the changes of your local database and deploy them to a production database using the migration history so the command we want to use is the migrate Dev next up we can give a name to the migration and just call it init so the name is going to allow us to identify in a name with the migration to make it easier to identify later so after you execute to migration you should see it complete successfully and afterwards it also generates a Prisma client types for us and essentially what this is doing is it's generating typescript types for US based off of our schema which we can actually use in our application code which is going to be really useful later on so now that the migration has occurred you can see it's created a new migrations folder and within here we have the Tim stamp of the migration as well as the name which in this case we called init so since we ran this as the development migration we can see the underlying SQL that was created which is required to get the state of our connected database equivalent to that of our Prisma schema now finally Prisma actually executed this migration against our database so let's go ahead and check that out so back in my SQL workbench I'll go ahead and refresh and now you can see under tables we have two new tables that have been generated the first of which is the Prisma migrations table and this is a system table that Prisma uses to determine if it needs to apply existing migrations to a database so this table is used when we run Prisma migrate deploy to determine if a migration needs to get executed or not based off of the check sum which is just a hash of the migration next up we can see we have the product table that Prisma has created for us which is excellent now we can see all of the properties that we defined on our model as columns inside of this table additionally if we look at the indexes for this table we can see that we have the primary key specified as the ID thanks to our ID decorator and then we have the index for the product name which is a unique index thanks to our at unique decorator to ensure that no two products have the same ID or name so has taken care of everything necessary to get our database ready to work with our application let's go ahead and start utilizing the types that Prisma client has generated for us in our application all right so let's get started and the first thing I want to do in our source directory is create a new database folder and in here I want to generate a new database module and database service so we can use the nest CLI to easily generate this I'll generate a new database module using nesg module database and then I want to generate a service called database. service which we can use the CLI for as well so this has automatically created a new database module for us added it to our app module and importantly it's created a database service which I now want to use to actually connect to Prisma so to do this I'm going to make this database service it extend the Prisma client and I also want to implement on module in nit from nestjs common and this is going to do two things firstly since we're extending Prisma client we're going to be able to inject this database service and make use of it anywhere in our app and access all of the types that Prisma client generated for US based off of our Prisma schema secondly since we're implementing on module mod and nit we'll have to call on module and nit and then I want to call await this do connect to connect to our database on Startup and then make sure this function is async okay so now that we have our database service let's go ahead and start building out a crud API around our models so to do this we can again take advantage of the nest CLI to generate boilerplate code for us so let's run Nest generate resource and call this product so this is going to ask which transport layer we want to use we'll specify a rest API and then we tell it yes we want to generate crud entry points so what this is going to do is it's going to create a new products folder in our project and inside of here it creates a products module with a products controller and products service so the product controller has all of the crud API routes already created cre necessary to implement crud functionality which is excellent It's also gone ahead and created a product service for us which is just implementing some stub string data for now we're going to refactor this to take advantage of our Prisma database and Implement true crud functionality so that we can create read update and delete data so back in the products controller let's go ahead and get started with our create function so right now you can see we're accepting a body and the body is defined as a create product dto so nestjs also has created some boilerplate dto an entity for us around the product let's go ahead and delete both of these folders because Prisma client has already generated these types for us and we don't need to duplicate them let's go ahead and remove the Imports to them in our controller and now in the create function for the create product dto we can actually specify the type directly from Prisma client so to do this we're going to reference Prisma from Prisma client and then we're going to access theproduct create input so because we ran Prisma generate after our migration Prisma automatically generated these types for us and added them to the Prisma client so we can access them and of course this is all based around our existing Prisma schema so if we actually look at the product create input we can see it matches exactly the schema we've defined in our Prisma schema so these generated types save us a bunch of time and duplicate code because now there's a single source of Truth for what our entities actually look like and it's all coming from our Prisma schema so we're passing this dto into the product service create function now let's go ahead and actually persist this product to the database so to do this we'll firstly go ahead in our Constructor and make sure we inject the private readon database service of type database service and in order to inject the database service into this product service we're going to make sure that we go back to our database module and in our exports array we want to add the database service so that it can be exported and injected elsewhere secondly I want to decorate the database module with this at Global decorator which is going to mark this module AS Global and it essentially just means that when we import it once we don't have to repport it every other time we want to use it so since we're actually importing the database module in the app module The Nest CLI has done this for us automatically we won't have to reort it in the products module which is great okay so in the product service we now have access to the database service let's go ahead and remove these old dto and now let's change this method into an async method since it'll be asynchronous and instead of returning the sub text we're going to return this. database service and now on the database service this also has access to all of our entities in our Prisma schema so we want to access the product which we can see here exposes all the crud operations for the product model so on the product entity we want to call do create and we can see all of the different operations that Prisma supports on these entities here so we want to call do create now we're going to open up an object where we simply need to specify the data property which we can see is the data needed to create a product and this will be the create product dto which will change the type two which we know is Prisma do product create input and so now we have everything we need to actually create a new product in our database let's go ahead and implement the find one method next so that when we create a product we can find it and make sure everything is working properly so to do this we want to find a product by its ID so we can take advantage of the database service again and call this. database serviceproduct and we can callind unique on it which will find zero or more products that matches a filter so now we can simply pass in a filter object to do this we simply provide the wear clause which is the actual filter for the product and on this we specify the properties that we want to filter for on this particular product so we can see it actually knows what properties exist on a product and that we can filter for so we could filter for the ID the name availability any field that exists on the product we can filter for it on our wear clause in this case we're only concerned with the ID so let's pass that in finally we'll change this method to be async as well next up let's Implement find all so we'll make this an async method and I want to return everything from the database in this case so we'll simply call this. database service. product. find many and to return everything we'll simply pass in an empty filter now this takes in the same properties we've already looked at including the wear Clause so we could easily filter for the products we want to return in this case I just want to return all of them so next up for the update method let's go ahead and keep the ID ID that we want to look for which is the ID on the product we want to update and then we'll change the update product dto to be at Prisma do product update input so now we'll utilize this by returning this. database service. product. update which we can see will update a single product so this takes in the where clause which is the filter for which product we want to update so we'll pass in the ID for the current product and then we have the data property which is the new data to be updated on this particular product so let's go ahead and pass that in by providing it the update product dto now finally for remove this will be very simple we'll make it a sync and then we will return this database Bas service. product. delete and then we simply pass in as you can guess a wear clause and this case we will pass in the ID of the product we want to delete so we can see how easy it is to implement crud functionality on a Prisma database thanks to these generated types and a very elegant and simple API let's go back to our products controller and update it to use our refactored product service so the post method is already working as expected since we're passing it to product create input the find all takes no arguments so we'll leave it as is next up we have the get route which is simply extracting the ID as a path parameter so we take that and then pass it as a number after casting it this is the ID for the product we want to find so this is all good and then we have a patch method to update a product so this is taking the ID as a path parameter for the product we want to update and then we accept a body which is the update product DL so we simply need to change this to be of type Prisma do product update input now we're passing in the correct arguments finally delete works just The Same by extracting a path parameter and this is the ID of The Entity we want to delete so now we fully refactored our app to work with crud functionality on Prisma let's go ahead and test it out in Postman all right so let's go ahead and get started I've opened up Postman and I'll launch a post request at Local Host 3000 where our server is listening and then I want to pass it in a body so I'll pass in a raw body of type Json and let's now provide a Json object firstly we'll provide the name so so we'll have a product called shirt we'll sell a shirt and then we'll give it a price I'll say it it will be $9.99 and then finally for the availability property I will say it is online and we'll also make this uppercase to match our schema so these are the three properties that are required on our entity and not optional so let's go ahead and make sure we send this post request to slash products where our controller is listening and we know this because of the controller decorator where we have the product string which is the prefix for this particular controller so now if we launch this request to create this product we can see we have a 2011 created response and we have the product that was just created sent back to us so we have the autogenerated and Auto incrementing ID the name and then we have the created ad and updated at timestamps which are generator for us automatically and we have the sale prop which is defaulted to false so we can see all of our data looks just as we'd expect and now if we go back to our database we can reexecute the query on the product table and see all of this data persisted to our database just like we would expect which is excellent now if I were to try to send this same product again you could see we have an internal server error and if we look at the logs we can see that the call failed because of a unique constraint on the product name key so it was excellent to see that our unique constraint is working on the product name let's go ahead and change this to a sweatshirt instead and this should be persisted now since it's a different name and we can see it updated and it also Auto incremented our ID for us so let's go ahead and test out the rest of our functionality I'll launch a get request to find a single product and remember this is a path parameter so we'll Target slash1 which is the ID of the product we want to find and then we simply get the product returned back to us next up let's go ahead and test our update functionality by launching a patch request at this and let's say we want to change the price to be $4.99 and the sale is now true because the product is now on sale so if we launch this request we can see that the price in sale has been updated as well as the updated property to reflect that this has now been updated so this is working great let's go ahead and launch a final delete request to delete this product you can see we have a 200 okay sent back and now if we launch a get request at the root path of products we should expect to see just a single product since the other one was deleted so we can see all of our routes are working and the crud functionality out of the box is working great all right so next up we're going to review relations in Prisma so a relation is a connection between two different models in our schema so if we go to our existing schema we only have a single model right now so we don't have any relations let's go ahead and create some new models so we can introduce the different types of relations in Prisma so the first relation we're going to explore is the one: one and this is the relation where where one record can be connected on both sides of the relation and only one record so for example in our case we have a product and then we're going to introduce a description for that product so a product will only ever have one description and the description will only be associated with one product so it's a on toone relation let's go ahead and create this new model called description and on this description model we're going to again have an autogenerated ID of type int so to do this we'll use the default decorator and then pass in the autoincrement function and then Target the at ID as well so that we have a primary key identified and a unique index will be created on the ID as well next up we'll have a Content field of type string which will be the actual content of the description so next up to actually associate this description with a single product we need to use the app relation decorator so in doing this we're going to introduce two new fields that are going to be responsible for linking this description to the product the first will be the product field of type product and this is what's going to actually introduce the relation between the description and the product using the at relation decorator so importantly this product field doesn't actually exist in the database it merely exists in the schema to tell pris how to associate a description with a product given a foreign key which we're going to provide next so let's go ahead and introduce the foreign key on the description in this case we'll just call it the product ID and this is going to be the foreign key that Associates this description with the given product so we know this is going to be of type int since it's going to match the ID field for the product so now we're going to reference it inside of the relation decorator by using the fields property and then passing in the product ID and then we need to tell it which field on the product model that the product ID is actually associated with so we do this by passing the references array where we can pass in the ID field which is the field that we want to Target inside of this product given this product ID forign key finally make sure to add the at unique decorator on the product product ID so Prisma is actually smart enough right now to warn us that this relation we're trying to create doesn't actually exist yet because we haven't added the corresponding field on the product model to associate the description on this one toone relation so in order to complete the onetoone relation we need to update the product model with the description field and then we're going to set this equal to the description model we also need to make this field optional because Prisma is warning us that it can't enforce that this description will always be available on this product model in case the corresponding description could potentially be deleted so we can mark this as optional by using the question mark operator all right next up we're going to look at the one to many relation which refers to relations where one record on one side of the relation can be connected to zero or more records on the other side so in our case we're going to have a single product that can be associated with many different reviews on that product so let's create a new model called reviews and on the review we're going to have the ID property as usual so let's go ahead and add that next up we have a title of type string content of type string a rating that's going to be an integer and then finally we need to again associate this review with the owning product so to do this we're going to do exactly what we did before by having a product and product ID field on the review to correlate it using its foreign key now we'll have to go back to the product and also add the reviews field which we know will be of type review and this will be an array because we're going to have multiple reviews on one product and make sure to go ahead and correct our reviews to just be review now finally we're going to look at the many to many relation which refers to relations where zero or more records on one side of the relation can be connected to zero more records on the other side so in our case this is going to be a product which can be associated with many different product tags the difference with the reviews is that these tags can be associated with many other products so it's a many to many whereas with the reviews even though there's many of them each review is only associated with a single product so that's the difference between the many to many and one to many let's go ahead and introduce our last Model called tag we're going to go ahead and simply add in the ID which we've used before to Mark the primary key and then I'm going to copy over the content field which will be the actual content of this product tag and now finally to associate this tag with the products that own it we are going to have the products field and this will be a type a product array because there's multiple products that this Tag's associated with and Prisma also doesn't require a relation decorator in this case so we simply need to go back to the product and finally describe the tags with the tags field of type tags array so now we've built out our product model with these three different types of relations let's run a migration against our database so that these updates to our schema will be applied to the database as well as our Prisma client types will be updated so we can now utilize these new models in our application lastly make sure we remove the unique constraint from the review since we're going to allow multiple reviews to be associated with a given product ID we don't want this to be unique however in the case of the description the product ID has to be unique since only one description will ever be associated with a given product that's not the case for our review okay so to execute our migration we're going to run the same command as earlier pnpm Prisma migrate and then we're going to use the dev command so that we generate the SQL migration script in our migrations folder and next up we're going to give this a new name we'll call this relations since this is the migration where we introduce these different models and relations so you can see the migration succeeded our database is now in sync with our schema and the Prisma clim Cent was generated for us we can go back to the database now and right click on our database to refresh all now you can see these new tables that have been added including the description model with all the expected Fields as well as the review model and our tag and Prisma also generated this product to tag table which is a system table in order to record the Rel relationships between our many to many relation of products and tags this is how Prisma maintains the relations since we don't have a foreign key on a given tag however if we look at one of the other entities like a review you can see it has the product ID forign key stored on it so Prisma doesn't need to maintain these relations in a separate table okay so back in Postman we're going to launch another request to create a product however this time I want to create a description and some tags along with it now since in our API in our product service we're simply passing our dto down as the data field we can take advantage of relation queries or in this case relation rights which allow us to use nested rights in our call to create this product so in order to accomplish this we're going to to set the description property first to create a new description for this product product and to do this we open up an object and specify the create property to tell Prisma that we're creating this entity so as we know from our schema the description will have one property called content and we're going to call this a good siiz basketball for our description and then we're going to do the same thing for tags so I want to create some new tags along with this product so we'll again use the create property and and now we can accept an array since this is a many to many relation we can create multiple tags at once so let's do that we'll create a first tag which has that content property and we'll call this Athletics for the first tag and then we'll go ahead and create another tag so another object with the content property and specify a tag of balls now also change this to be a baseball instead because we have already created a basketball so will have a duplicate key on it so we'll change out the description as well for a baseball and now if we create this we can see we have the product created so now in our database let's go ahead and run a query to look at the tags in our system now so now at this point you can see I have new tags created that we just inserted with our product including one called balls and another called Outdoors so these tags were successfully saved in our database additionally we've created a new description so if we look at the description we can see a good siiz baseball and of course we have the corresponding product ID that links this to a product in our product table so this is the foreign key and if we look at our product we can see we have the baseball and its ID matches the product ID finally we can see in the product to tag table that we actually have this mapping of a column which in this case is the product the owning product and the tag itself since it's a many to many relation we keep track of it here in this separate table now by default our API didn't return back any of these linked relations and that's because we need to explicitly tell Prisma whenever we want to get back any relations on an entity since these foreign key lookups will incur some performance hits however it's still much quicker than making multiple calls to the database to form our own model so let's go ahead and see how we can actually pull back these relations we'll do this in the find one query so in addition to the where object we have the include object which allows us to specify which relations we would like to include in the query so in this case we'll specify the description to true the tags to true and we'll also include reviews which will add later so now if we execute a request to get this product with the ID of six we'll change the url and get a get request we can see we not only get back the product we get back its corresponding description and all the tags associated with this product of course there are no reviews right now so you can see how easy Prisma makes it to include these relations and this relation object is available in pretty much all calls to the Prisma client so you can include these Foreign Relations whenever you're interacting with one of your models okay so finally I want to create one more resource in our application and this is going to be for the reviews on the given products so let's generate a resource called reviews we'll go ahead and use a rest API and also generate crud entry points so now we have a reviews resource with a reviews controller exposing this crud function functionality on a given review okay so next up let's actually copy the existing class code for our product service so that we can simply paste it into the review Service as most of this crud functionality is going to stay exactly the same we'll firstly need to make sure we import the database service and Prisma as well from Prisma client and then what I want to do is open up my file edit replace and I want to look for all usages of the product word and make sure it's case sensitive and replace this with a review so now you can see we are interacting with the review property on our database schema instead of the product and then next we'll do the same for product with a capital P so I want to change this to review with a capital R and now at this point most of our code is working out of the box we simp simply need to remove these references to these dto and now in find one let's remove the include object since we're not going to include any relations and now the review service has been refactored to have crud functionality instead of reaching out to the product we're reaching out to the review now so let's go to our reviews controller and we'll update our create review dto to be from Prisma do review create input just like we did in our product controller and we can remove the references to the dto as well let's go down to the update method and change the update review dto to be Prisma do update. review update input and now the review controller is working out of the box with crud functionality let's go ahead and test it out back in Postman so now we can launch a post request at/ reviews Target our reviews control controller so back in Postman I'll create a new duplicate Tab and now let's target SL reviews to Target our reviews controller now in the body we're going to change this out to match a review schema so we have a title firstly and we'll say great product next up we'll specify the content and say this is really great next up for the rating we'll provide the integer of four finally we need to specify the product ID that this review is associated with so we'll go ahead and Associate it with our product ID of six or this baseball that we created so if we go ahead and send off a post request we can see this gets created now if we go back to our reviews query and actually execute the request to get a review of type of id6 now and send this request you can see that the review we created to this product has been populated in the reviews array now since this product ID is associated with our baseball product this relation query is going to populate the review that was created and associated with this product and of course if we make any updates to the review that will be reflected as well so hopefully you've learned a lot about how we can utilize nestjs in Prisma to easily interact with our database entities Implement cred Behavior do migration and include relational queries out of the box with little effort thank you so much for watching and I'll see you in the next one
Info
Channel: Michael Guay
Views: 8,508
Rating: undefined out of 5
Keywords:
Id: skQXoZ8chxk
Channel Id: undefined
Length: 51min 41sec (3101 seconds)
Published: Wed Oct 18 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.