Database Workflows & API Development with Prisma

Rate this content
Bookmark

Prisma is an open-source ORM for Node.js and TypeScript. In this workshop, you’ll learn the fundamental Prisma workflows to model data, perform database migrations and query the database to read and write data. You’ll also learn how Prisma fits into your application stack, building a REST API and a GraphQL API from scratch using SQLite as the database.


Table of contents:
- Setting up Prisma, data modeling & migrations

- Exploring Prisma Client to query the database

- Building REST API routes with Express

- Building a GraphQL API with Apollo Server

98 min
14 Feb, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Welcome to the Database Workflows and API Development with Prisma workshop. Prisma is an ORM that allows you to work with a relational database from an object-oriented programming language. The workshop covers topics such as data modeling, migrations, using Prisma Client for querying the database, and implementing REST and GraphQL APIs. It also highlights the benefits of Prisma, including its intuitive data modeling language, type-safe database client, and migration tool. The workshop provides hands-on tasks and guidance for beginners to get started with Prisma.

1. Introduction to Prisma Workshop

Short description:

Welcome to the Database Workflows and API Development with Prisma workshop. Today, I'll introduce you to Prisma and cover the most important workflows for building an application with Prisma. We'll start by setting up Prisma with a SQLite database, then learn about data modeling, migrations, and using Prisma Client for querying the database. We'll also explore implementing REST and GraphQL APIs using Prisma Client. No prior knowledge is required, as I'll provide the necessary resources and guidance. Feel free to ask questions and follow along as I explain each lesson before giving you time to work on the tasks. I'm Nikolas, the host of this workshop, and you can connect with me on Twitter, GitHub, email, or the Prisma Slack. This workshop is free for you to use and share with others.

Welcome to the Database Workflows and API Development with Prisma workshop. I'm really excited to give this workshop today. Actually, these kinds of workshop are pretty much the favorite part of my job as a developer advocate who works at Prisma to work with people and show them kind of their first steps with Prisma. And that's exactly what you'll be doing today. So no need for any prior kind of knowledge about SQL or TypeScript or anything. We'll start from scratch and I'll introduce all the relevant concepts so that you don't need to know anything upfront.

One thing that I would ask all of you to do is to take this link that I'm now also dropping in the chat and open it because then you can see also this Notion document that I'm using here right now. And just for logistics, I have a second screen here to my left where I'm monitoring the chat. So forgive me if I'm not always looking directly at you all. I'm just checking what's going on in the chat and if things don't work or if you have a question, you can always drop that in the chat or because as I already mentioned, we do a regular Zoom call here. You can also just unmute yourself and then ask a question. So that's definitely possible here as well. An issue that like Notion SO doesn't work for encrypting. I actually don't have another source. I didn't have problems so far with Notion, but it's also not too big of a deal if you cannot open it yourself because I will walk everybody through the document. And what I can do is I think I can export it as a PDF. I can do that later when you get to work on your first task and then I can send you over the PDF document. So we should be able to resolve that. All right. So welcome again, Database Workflows and API Development with Prisma. So what you're going to learn today is basically the most important workflows that you have to be aware of when you want to build an application with Prisma. And I'll explain in a little bit actually what Prisma actually is and what it does. But first I want to give you a rough overview of what we're covering in this workshop. So at first we start by setting up Prisma with a SQLite database. You learn about data modeling with Prisma and performing database migrations. Then you learn about Prisma Client, a typesafe query builder that can be used to query your database. And you're going to explore various queries there from plain CRUD to relation queries to filters and pagination. And next you'll learn how you can use Prisma Client to implement the routes of a REST API and then also the resolvers of a GraphQL API. And you don't have to know what a REST API actually looks like, what a GraphQL API looks like. I prepared kind of the boiler plate for you. The skeletons of the projects that you're going to be working with. So if you haven't heard of what a GraphQL resolver is for example, that's not a problem at all for this workshop. Ahem, so this is the high level agenda. Actually I realized that it's all one hour too early. So that should be like starting at four and then you add one hour each time. What does a lesson look like? So I prepared these four lessons that map to the different things that we want to do in the workshop. So setting up Prisma, data modeling and migrations, exploring Prisma Client, Rest API and GraphQL API are the lessons. And each lesson looks as follows that at first I'm going to give a walkthrough of the lesson. So for example, for the first one here, I click on it and then I'm going to explain what you are supposed to do in that particular lesson. And I'll even show you like here with my terminal, with my VS code, a little bit of the task that you're going to be working on. And after having shown you maybe three or four tasks per lesson, you'll get the time to work on the tasks of that lesson by yourself. And what I really want to emphasize for you all here to get the most out of this workshop is to not already code along when it's still me doing the walkthrough. So I think it's really best if when I show you what a lesson is going to look like, when I explain the individual tasks that you just pay attention and that you raise any kind of questions that cross your mind, but really focus on the things that I do, that I say, and try to understand that. And after that, you'll have plenty of time to actually finish these tasks yourself. So be a little bit patient when I'm explaining each task and each lesson and then you'll make the most out of the workshop for yourself.

My name is Nikolas, I'm the host of this workshop. I really like to educate other developers and as a developer advocate of Prisma, that's basically my main job. And you can follow me on Twitter, on GitHub, you can drop me an email or you can also find me on the official Prisma Slack. One final note before we dive into the topics is that this workshop, this like Notion document is completely free for you to use if you want to host this workshop for yourself at some point. So if you feel like what you've learned in this workshop today is really valuable and you would like to share it maybe with your colleagues or with friends and like maybe like some of them are up for like spending a few hours with you on this then you can just reuse all of these materials that I've put together here and use them when you're giving this workshop yourself.

2. Introduction to Prisma

Short description:

Before we start with the lessons, let me give you an overview of what Prisma is. We'll visit the Prisma website and explore the landing page together. Feel free to ask questions and join in the conversation about databases and object relational mappers.

All right, I think that's it with the overview for the logistics. All right, before we start with the actual lessons I would quickly like to give an overview of what Prisma actually is. And the way how I want to do that is actually just by going to the Prisma website and give you all a quick walkthrough over our landing page because I think that's probably most instructive here. And if you have any questions along the way also feel free to unmute yourself and drop in, I want to make this kind of as interactive as possible. And if we want to have a conversation here about databases and object relational mappers that's totally fine with me as well. So if anyone here actually has strong opinions about this topic, then feel free to join me here.

3. Overview of Prisma

Short description:

Prisma is an ORM that allows you to work with a relational database from an object-oriented programming language. It provides an intuitive and straightforward data modeling language to describe the schema of your database. With Prisma Client, you can query the database using a type-safe database client. Prisma also offers a migration tool, Prisma Migrate, to track changes to the database schema. While Prisma is commonly used on the backend to implement queries against the database, front-end developers can also use it with frameworks like Next.js or Remix that allow server-side code execution.

All right, so Prisma is an ORM. ORM is an abbreviation that stands for Object Relational Mapper. And like those of you who have worked with relational databases you might have already experienced working with an ORM as well. What basically is an ORM? It is a tool that allows you to work with a relational database from an object oriented programming language. So the O stands for object and the R stands for relational. And that's because the tool, the object relational mapper is mapping the data structures from the relational database into the object oriented programming language.

And Prisma is a new kind of ORM that's really not comparable to any other ORMs from the space, so you might have heard of libraries like SQLized or TypeORM that fall into the more like into the previous kind of generation of ORMs where you're defining your tables as model classes. And then you instantiate these model classes to query the database. The way how Prisma works is actually quite different and you'll experience today what these differences are.

So like, first and foremost, I think what really is a strength of Prisma is the way how you model data with it because we have a very intuitive and straightforward data modeling language that lets you describe the schema of your database. And here is an example of what that looks like. It's a lot more readable, I think than if you were to use like TypeScript classes, for example, with decorators where we have a lot of noise. And here it's really just the essential information that you need to define your data structures. Once you have defined your data model, you can then go and query your database with Prisma Client, a type safe database client. And that's also a bulk of the workshop that we're doing today for you to kind of get familiar with the Prisma Client API, learn what kind of queries you can send to the database and how to use Prisma Client in general. And of course, almost all object relational mappers also come with a way to create migrations against your database. And that migration is really important when over the time of your project, the database schema changes and you then need to kind of track the history of these changes against your database schema. And that's what migrations allow for. And with Prisma Migrate, one of the tools that Prisma contains, you really have an easy time to track the migrations that are happening against the database. And if we zoom out on a very, very high level just for kind of everyone to be on the same page, I guess that those of you who rather work on the backend or maybe a full stack developers that already have experience with building kind of your own server, your own server side application, you already have a good understanding that this is where Prisma is being used, right? It's being used on the backend to implement the queries against the database. If you're only a front end developer, then it's unlikely that you're going to use Prisma directly because it's not really something that you would use inside of your React application. However, with new frameworks, such as Next.js or Remix that typically give you the chance as a front end developer to also run some kind of server side code, like be it via static side generation or a server side rendering, or a Next.js with API routes. There are a lot of different kind of mechanisms that now allow front end developers to also use Prisma in the comfort of their own framework, but only when these frameworks actually allow in some capacity to actually run server-side code as well. That's when you would use Prisma also in a front end framework. But the majority of use cases for Prisma I would say are typically on the backend when building an API server. And I think that's also reflected by the popular technologies that we have listed here which for the most part are backend technologies.

QnA

Diving into Lessons and Setting up Prisma

Short description:

Let's dive into the lessons, starting with setting up Prisma. The goal is to get comfortable with Prisma's data modeling and perform your first database migration. There's a question from Amal about full-stack JavaScript, and I recommend Redwood JS or Next.js for your project. Deployment is not covered in this workshop, but you can use any deployment provider like Heroku or Vercel. Let's get back to the setup and clone the starter repository, install the node dependencies, and open the project in your preferred text editor.

All right, are there any questions about Prisma so far about anything that I said, about anything that's unclear about the workshop or should we dive in and start with the lessons? So let's go ahead and dive into the lessons.

So let's start with lesson one and setting up Prisma. The goal of this lesson is to set up Prisma getting comfortable with Prisma's data modeling and perform your first database migration.

Oh, there is one question from Amal that I can quickly take before moving on in the lesson. So yes, what's up Amal? Hello. Hey there. Do you hear me well? Yes, very nice. Perfect. Okay, so I sort of have a question which is not related to Prisma, but related in general with the full stack GS, if I may can ask. Okay, so perfect. The thing is that I'm an IT student and I have my project this year and I actually like made a training concerning the full stack JavaScript, like the package MERN. And I haven't touched the code for like six months and I have to like start right now and do like a B2B Schedule Meeting Platform. And I don't know where to start, like, it's sort of the blower. So it's kinda I need a year in advice about this. I see. And you said that like you already have a project from six months ago that was using the MERN stack? Actually like I had it training like six months ago, but I didn't touch the code. It's been six months. I see. Okay, so it seems to me like what you're kind of looking for basically is like sort of like a full stack solution to build the project that you're tasked to build there. And what I would recommend actually is a tool called Redwood JS, which is a like full stack framework that takes care of the front end and the backend for you. So you might want to look into that. I've heard a lot of good things about Redwood. And there are a couple of similar frameworks. If you don't have the need for very complex business logic on the backend, then you could also just go with Next.js, which also allows you to run like server side code and to integrate API routes so that you wouldn't have to build your own express server, for example, because the API routes are already included in Next.js. So these are probably the two frameworks that I would recommend to you just off the top of my head. And yeah, if you have more specific questions about how to get started, we can also like follow up about this after the workshop and I'd be happy to share more advice. Yes, sure. Thank you so much. I really appreciate it. All right. Thank you. You're welcome. Thank you. And I will ask you like after the workshop. Okay, great. Okay. Another question here from Amandib. Would we deploy our app today as well, including the Prisma database? So, one clarification here, Prisma is not a database. It's only a layer that you can put on top of your database. And in terms of deployment, that's not planned in the scope of this workshop today. To me, it's rather important that you learn about the basic workflows with Prisma and the ability to query and like migrate your database. But we won't go a lot further in terms of application development because then Prisma is basically only a library and your application and there is not like nothing too specific, for example, about how you deploy your application then. So, you would use a deployment provider as for any other app like Heroku or like Vercel, DigitalOcean, like wherever you prefer to deploy your apps these days. And you can do that with Prisma as well when you integrate it into your project. That being said, let's get back to the setup and I have prepared this starter repository here and I'm just going through the steps that you are doing afterwards as well. So, I'm like copying this command to clone the startup project. Then, inside of the startup project, we have these instructions as well to then install the node dependencies. And once you are done with that, you can open the project inside of VSCode. Now, you don't have to use VSCode for this workshop. Prisma also works, of course, or just with any other text editor that you might be using for development.

Creating User Model and Migration

Short description:

I recommend using VSCode for its excellent Typescript support and the VSCode extension we built for Prisma. After setting up your project and installing dependencies, you can start with the first task. Prisma uses schema.prisma files for data modeling, where you define data sources and generators. You can choose the database you prefer, such as SQLite, Postgres, MySQL, MongoDB, or cockroach DB. The generator block instructs Prisma to generate the Prisma Client Library for querying the database. The task involves creating a user model with ID, name, and email fields. The name field is optional, while the email field is required and unique. Once the task is completed, you can expand the solution and proceed to create a migration using the Prisma Migrate dev command. This command creates migrations locally in development. The resulting migrations folder contains the SQL code executed against the database.

But I would recommend to use VSCode because they have really good Typescript support. And we also built a VSCode extension that helps you with syntax highlighting, and linting, and quick fixes of Prisma schema files that we're going to take a look at in a bit as well.

So once you have done this and you have your project ready here and installed the dependencies, you can get started with the first task. And please remember that you will have your own time to work on these tasks. And for now I think it's just best if you follow what I'm doing here.

So I have already mentioned in the initial intro that Prisma has a very straightforward way to do data modeling and that's always done in these schema.prisma files. So.prisma is the custom file extension that we use for Prisma schemas. And at the moment we have defined two blocks inside of the schema. One is data source and one is the generator.

With the data source we just configure our connection to the database and we tell Prisma that we want to use a SQLite database in this case. And also where to find that database. And here we could also use like for example Postgres or MySQL, the MongoDB and cockroach DB connectors are currently in preview but you can already start using them. So you have the flexibility to choose the database that you prefer here with Prisma.

And then we also have these generator blocks that are actually quite interesting but for now I just want to point to the fact that we're telling Prisma to generate the Prisma Client Library that will later allow us to send queues to the database from our Node.js application. All right.

So let's look at the task here start by creating the following user model with the following fields and choose the data types that feel the most appropriate to you based on the description below. So we have to create a new model here and I'm going to show you how that works in just a bit. And we have to add these three fields, ID, name and email.

I will make both of them strings, the name is supposed to be optional. And if I have an optional field in the database, I can annotate the field in the Prisma schema with a question mark. And I also have the email, that's also a string. This one is required in the database. So I'm not putting the question mark and I'm also adding the unique attribute here.

So once you're done with this task, you can expand the solution here and see if you are correct. And the next task is to then go ahead and actually create a migration. And the command that you're going to use for this is the prisma migrate command. Migrate and if I just run the command like this, then you'll see all the different options that you have as sub commands for Prisma Migrate because like Prisma Migrate is a command that then accepts sub commands and options in the CLI.

And in this case, I want to use the Prisma Migrate dev command, which is used to create migrations locally in development. When you actually want to apply your local migrations against your production database at some point, that's when you're going to use Prisma Migrate deploy. But that's also not in the scope of today's workshop. So I can now run the Prisma Migrate dev command and I can provide the name for the migration that's being created as an option here as well.

And let's see what actually happened on the file system now because a few things have happened. We see that there is this new migrations folder right here. Increasing the font size just a little bit more. And in this new migrations folder, we also have this new folder that's called this long number which reflects the current timestamp and then the name of the migration that I provided in it because of my first migration. And we can actually see the SQL code that Prisma has executed against the database. So it just ran this SQL code against the database and created the database file right here where I told it in the Prisma schema where I would want the Dev DB file to have.

Creating Migrations

Short description:

To create a migration, use the prisma migrate command. The Prisma Migrate dev command is used for creating migrations locally in development. Prisma Migrate deploy is used for applying local migrations to a production database. This workshop focuses on local development.

And the next task is to then go ahead and actually create a migration. And the command that you're going to use for this is the prisma migrate command. Migrate and if I just run the command like this, then you'll see all the different options that you have as sub commands for Prisma Migrate because like Prisma Migrate is a command that then accepts sub commands and options in the CLI. And in this case, I want to use the Prisma Migrate dev command, which is used to create migrations locally in development. When you actually want to apply your local migrations against your production database at some point, that's when you're going to use Prisma Migrate deploy. But that's also not in the scope of today's workshop.

Running Migrations and Adding Data

Short description:

After running the Prisma Migrate dev command, a new migrations folder is created with a timestamped folder containing the SQL code executed against the database. Prisma Studio, a GUI for the database, is used to add data to the database. Three records are added in this lesson.

So I can now run the Prisma Migrate dev command and I can provide the name for the migration that's being created as an option here as well. And let's see what actually happened on the file system now because a few things have happened.

We see that there is this new migrations folder right here. Increasing the font size just a little bit more. And in this new migrations folder, we also have this new folder that's called this long number which reflects the current timestamp and then the name of the migration that I provided in it because of my first migration. And we can actually see the SQL code that Prisma has executed against the database.

So it just ran this SQL code against the database and created the database file right here where I told it in the Prisma schema where I would want the Dev DB file to have. So we now have a database and one table in the database already. So the next step is to actually create some data in the database. And in this lesson, we are not yet using Prisma Client, but instead we were using a tool called Prisma Studio, which is basically a GUI for your database. And you can use it to put data into the database like this. I'm adding three records here and save the changes. And now I have three records in the database that I just created.

Rollbacks and Prisma Client

Short description:

Rollbacks are now possible with Prisma Migrate, providing a better way to handle down migrations. Automating the migrate command while editing the Prisma file is not currently possible, but you can submit a feature request on our GitHub repository. You can close Prisma Studio after editing the data or keep it open for later use. We won't cover Prisma seed in this workshop, but you can find a guide in the Prisma documentation. Updating to the latest version is not necessary for the workshop. In the next lesson, we'll explore Prisma Client and learn about CRUD, relation queries, filtering, and pagination. You'll run another migration to introduce a second model with a relation to the user model. You can test the code with NPM run dev and execute Prisma client queries against the database.

There is one question about whether it's possible to roll back migrations. And I'm very happy to share that this is one of the most common questions that we're being asked as Prisma. And as of the last release, actually, we have a really nice way. We introduced a really nice way in Prisma Migrate to work with rollbacks. So it is indeed possible. And I will just link you to a blog post here that we launched and explained how the rollback workflows work with Prisma Migrate. The short story is that it's basically a better way to do rollbacks and down migrations. Because with Prisma, you don't have to write a down migration before things go wrong, but instead you can figure out what went wrong in a particular migration and then basically decide if you want to move forward or if you want to move backward. And Prisma is going to generate the required SQL code for you. So, in terms of developer experience and in terms of safety and confidence in your database workflows, I think that this was a great step forward and Prisma now supports rollbacks for database migrations.

One question from Christian was, is there an option to automate the migrate command while editing the Prisma file? Do you mean in like a hot loading sense so that basically whenever you save the file that it would automatically execute a migration? That's how I read your question at least and it's not currently possible. We actually had a command like this in the past but we got rid of it because it showed to be like very complex to do it right. I think this could be a fun like side project for anyone if they're interested in what that looks like but because you're working with a database and changes against the database schema are somewhat at least delicate I wanna say to execute. I'm not even sure if it's necessarily desirable to have a tool that automatically picks up everything that you type and immediately executes it against the database. And so at the moment it doesn't exist. If you really wanna see it, you can always go to our GitHub repository and open a feature request and make a case there so that our product and engineering teams can then evaluate it.

Another question, can we close Prisma Studio after we're done editing the data? Yes, you totally can, but you can also keep it open and use it later again but you can also with the same command you can always bring it back up. So whatever is convenient for you. If you want to close it then you can definitely close it in VS Code because it's blocking your terminal of course, then you can just open another terminal tab here and that should also work. So that's up to you. Are we covering Prisma seed too? Unfortunately, we're not going to cover the seeding workflow with Prisma today but it's pretty straightforward. So I can link a page on the documentation that explains the seeding and yeah, it's pretty straightforward. If you search in the Prisma documentation for seeding we have a guide about this and I'm dropping a link to that guide in the chat. And then Evelyn is asking, if we should update to the latest version from 3.91 to 3.92, it's not really important for this workshop. So if that warning message annoys you then you're free to update but it's not necessary to successfully follow this workshop. Then there is Norma Moody and that also wants access to the PDF documents. So let me very quickly arrange that. Give me one second and then we'll continue with the next lesson. Okay, so that email is out as well. And there is one last question before we move into the next, Oh, actually, I just realized that I dropped the seeding link to a private conversation here. Now everybody should be able to see it. Another question about the def- and deploy-workflows because we can manage multiple environments simultaneously. And yeah, like, that's pretty much it. And then there are also some guard rails in the migrate-def command that will prevent you from doing things that you never want to do or as, sorry, in like migrate-deploy. You have some guard rails that prevent you from doing things that you never want to do against a production database. And you can read up on these commands also in the Prisma CLI reference here under the Prisma Migrate section. So we have a lot of documentation about all of these commands. So, all right, so I think pretty much everyone probably is done by now. And if not, then you can also just continue after I did the next host walkthrough. So now I want to show you how to get started with Prisma Client. So yeah, looking at the next lesson, exploring Prisma Client. The goal of this lesson is to get comfortable with your Prisma Client API and explore some of the available database queries that you can send with it. You'll learn about CRUD, relation queries, filtering and pagination, and along the way you will run another migration to introduce a second model with a relation to the user model that you created before. One thing to note is that we'll only work in this like VS Code project that you cloned from my GitHub, and it currently already contains the script.ts file, which is really just a very plain like TypeScript script that you can execute. So if you just want to test that it works, you can add this hello or some other logging statement, and then you can execute it with NPM run dev. And that's just executing the code and the script. So now you will have a number of tasks to write, like certain kinds of Prisma client queries. And then after you have written one of these queries, you can just run them against the database again by running the script with the NPM run dev command. A couple of hints that I want to point out before I get started here.

Writing Queries with Prisma Client

Short description:

Before we start writing queries with Prisma Client, I want to give you a few hints. It's recommended that you type the code yourself instead of copying and pasting. This will enhance your learning experience and allow you to use Prisma's auto-completion feature. To see the current state of your database, run the npx prisma-studio command. Now, let's write our first query to return all user records. We'll store the results in a variable called users and use the find many query. The next task is to create another user record with only an email value. We'll use the create one query for this. Finally, we'll update an existing user record by adding a value for its name field. We can use the update query and the where option to identify the user to update.

A couple of hints that I want to point out before I get started here. So I really want to recommend to you that you type yourself. So even I have to look up the solution by expanding the solution block here. I still recommend you to not copy and paste the code from that solution block, but still type it out. That has a lot more of an instructive and educational effect for you and your brain if you actually type these things yourself, and it also will enable you to experience Prisma's auto-completion, which is just a very nice feature in general when you're using Prisma.

That's also already the second tip that you can use auto-completion. I'll show you how that works. Whenever you want to see what the current state of your database looks like, you can run the npx prisma-studio command again and explore your data in Prisma Studio.

All right, so let's see how we can write queries with Prisma Client. Write a query to return all user records. To warm yourself up a bit, go and write a query to return all user records from the database. Print the result to the console using console lock.

So let's make our first query. I'm going to store the results of my query in a variable called users, and then I use the await keyword because Prisma Client returns promises for all of its queries. And here you can already see the auto-completion that we have available when using Prisma. And at the moment, it shows a lot of these top-level Prisma Client methods that are all prefixed with a dollar to avoid name clashes just in case the models that you defined in your Prisma schema conflict with the names that we gave to these higher level methods. But the most interesting right now is this one user property on the Prisma Client instance, which now gives us access to all the model queries that I can execute for this user model. So if I look at the auto completion I can see a ton of different queries that are possible here. And in this case, the appropriate one that just returns everything if I don't provide any further filtering or pagination is the find many query. And then I'm doing as told logging all the users using console log. At this point I'll actually stop Prisma Studio crash this one, and I'm only using this terminal. And now I can run npm run dev. And when I run this, I basically expect to see the three database records that I previously created with Prisma Studio to be printed to the console now. And that's exactly it. So Prisma client always returns playing JavaScript objects in this case an array of JavaScript objects and we can actually see the type of that array also when we hover over the user's variable right here. So that was very easy, very straightforward. Let's see what the next task is.

This task, you create another user record in the Prisma Client query, provide only a value for email but not for name. And the value for email should be ls.prisma.io. So again, I'm storing the result in a variable, I'm using await, I'm using the auto-completion to navigate my way to all the model queries on user, and I find the create one. And the create option, the create query, it takes an object where I can now provide the data that I want to provide when this record is being created in the database. And the task, it says I should only provide an email. And that's okay because only email is actually required. That's alice.prisma.io. Again, I'll log this to the console like this and run npm run dev. So that's worked. If I now were to create find many again, to run find many again, then we would see an array of four users that are being printed. But what I cannot do for example, is to run the same query with alice at prisma.io again, without an error. And that's of course, because we declared the email as unique in our database schema. So if I run this, so to prove my point to you here, npm run dev, I'm running the script again. I see an error and the error message says that a unique constraint failed on the fields email, which is true, right? We are violating the unique constraints that we defined in the Prisma schema. And that's why we cannot execute this twice with the same email at least. All right, so the next query is a query to update an existing user record. In this task, you will update the user record and you just create it and add a value for its name field. So let's go ahead and do that. I'll have, of course, to change my query here. So update seems like the right model query to use here. And now in addition to the data that I want to provide, so I want to set the name of this user to Alice, but I need to identify the user that I just created as well. And that I can do by adding this where option here. And what's very neat about using Prisma Client in this way is also that where now accepts all the fields from your Prisma model that are declared as unique, and these are ID and email.

Updating Record and Setting Name

Short description:

The ID field is not explicitly declared as unique because it is already implied in the ID attribute, which serves as the unique identifier and primary key for the model. The name field of a record can be updated by using the email as a reference. In this case, the name field is set to Alice for the record with the specified email.

And if you're wondering about the ID field here and wondering, but we didn't declare that one as unique explicitly. That's true, we didn't add the unique attribute here because we don't have to because unique is already implied in the ID attribute, which is the unique identifier, the primary key for that particular model. So that's why we don't have to add at unique here in particular. And I could now go and just use the ID of that record that I just created, but in this case I want to do it by email, aliceatprisma.io. So I'm running this and now the name is actually set to Alice on the same record that was just created.

Creating Post Model and Migration

Short description:

Let's create a migration and a second model called post. The post model will have fields for title, content, published, and author. The title field is a required string, while the content field is optional. The published field indicates whether a post is published or not, with a default value of false. The author field is a relation to the user model, using the author ID as the foreign key. Both sides of the relation need to be defined in the Prisma schema. Running the migration will create a new post table in the database.

Let's go ahead with the next task here and that's to create a migration and a second model or first the second model, then the migration in that order and we are adding a post model. So I'm using the model keyword again, I'm calling this model post and this first part, I can just copy and paste. All my models will have this configuration for their ID fields and now let's see what else we have to put on there. So we should put the title, the content, a published field and an offer on the post. So let's start, title is going to be a string and required in the database, so no question mark. Content is the content body of the post, this field should be optional in the database, so I'm adding the question mark. A published field indicates whether a post is published or not. This field should be required in the database and by default, any posts that is created should not be published. So how can I represent the state of published or not published, with a data type that's being supported by Prisma with a boolean. So it has two states, it's either published or not published and by default, I want this to be not published, so I'm adding false here. And then I also want each post to have an author and an author ID. So I'll start with the author ID and this author ID now actually is a reference to this ID field on the user model. I'll explain later what exactly that means. And then in addition to that, I can also declare this user fields or I have to declare this user field as a relation fields. So I have to mark it with the add relation attribute and that's just how you configure in Prisma when two models are related to each other. Under the hood, it's then using like foreign keys for this. And the way how you write this is that you tell in the relation attribute which fields of your current model should be the foreign key. So that's the author ID. And now you tell it, which fields it references on the user model. And that's the ID field in this case. And right now Prisma is not yet happy because Prisma always requires the both sides of a relation. So if you declare a relation between two models, it's not enough to only say on one side of the relation what it's supposed to look like but you actually have to do it on both sides of the relation. I'm also using the formatting again, and now I have a nice Prisma schema here that reflects the changes with a new model and with a relation between user and post via the author ID foreign key right here. The relation should be optional. So I also added the question mark to both the author ID and the author fields and to run the migration I'm just using the same command as before but I'm supplying a different name to the migration. If you're curious what happened under the hood again you can look at the SQL that was generated and really it only created one new post table with a bunch of columns in the database here.

Creating a New Post and Connecting with User

Short description:

Let's write a nested query to create a new post-record using Prisma Client. We can see the new post field on the Prisma Client instance, allowing us to invoke queries for the post model. After creating the post, we can connect it to a user using a nested query.

All right, let me do one or two more Prisma Client queries because before you get the time to work on this yourself. So let's go and write a nested query a query to create a new post-record. It's not yet a nested query. So now you can already see that in the auto-completion we now have this new post field on the Prisma Client instance as well that now lets us invoke the queries for the post model. And in this case, I'm creating new post. So nothing too fancy here. That's the same that we've done before. And we see that the post was created. It's being printed and the last query that I want to show is how to connect a user and post with a nested query.

Updating Post Record and Connecting with User

Short description:

To update the post record and connect it to an existing user, we can use Prisma Client's type-safe API. By finding the post by its ID and updating the author field with the email, we can connect the author to the post. This can be verified by printing all the posts and including the author using the include option. The console.table and console.dir commands can be used to display the data, especially when dealing with nested objects.

So we now have several users records and exactly one post record in the database. These can be connected by the author ID foreign key. When using Prisma Client, you don't need to manually set foreign keys, but you can configure relations using Prisma Client's type safe API. And we want to update the post record and connect it to an existing user via the email. So we don't actually want to set the foreign key, but we want to set the email. And I can still remember that it's the post with ID one. So I'm finding the post by its ID this time. And we then want to update the author field. So I'm using the data field inside of the update object that I provide. And then I can just navigate my way through with the auto-completion that I can invoke every time with Control, Space and Connect. And I want to connect the author via the ID. Email, sorry. I'm running this. And now I can actually see that this was successful because I can now see that this, which prior was now after I had created the record, now the author ID is set to four. And just to very quickly print all the posts that we have so far. I can use find many again to show you that this post was created. And then a cool thing that you'll explore a little bit later, but that I'm already showing you, you can use the include option in all the Prisma model queries as well to also fetch a relation. So if I now run this code, it's not going to print anything because I don't have a console log statement. Posts npm run dev. You can actually see that it prints the nested object because it was fetching the author for that particular post as well. So one hint first from Alexander was to use console.table, which I think is a very nice idea, especially I don't know if it also works with related data, but I also use sometimes console.dir. Let me see how it prints the relation here. Yeah, it says, this is an object. What's nice to print more deeply, like nested objects as this command with console.dir. Actually, depth null, not depth null. Yeah, perfect. So that also works, and it works nicer if you actually have like two or three levels of nesting.

Field and Model Aliases with Prisma

Short description:

You can use the at map attribute in Prisma to create field and model aliases. By using the map attribute, you can specify different names for fields and models in the database compared to the Prisma schema. This allows you to maintain consistency between the source of truth in the database and the naming conventions used in your Prisma schema.

Another question was from Fernando, what if I want to create a field with an alias? For example, store it in the databases updated at with spelled in snake case, but then I want to name it Prisma schema in... I want to name it in a camel case in the Prisma schema. And Romeo was the kind to already respond to that. It's indeed possible with the at map attribute. So I'm not going to change anything in the Prisma schema, but I'm going to show you how it works without running a migration. So if I wanted to do this now and I have this updated at, I want it to be camel case in my Prisma schema here, it's of type, like daytime. And then I can use map right here and say in the database, I want this to be called updated at. And that way when then Prisma Migrate creates the SQL, actually it would be spelled in, in snake case here as well, because that represents the source of truth for the database, right? So yeah, you can do this with at map on field names to map them to column names, but you can also do this with model names and map them to map them to table names. So if I wanted this post model to be called lowercase post, then I could do this. And now it would be lowercase post in the database and uppercase post in my Prisma schema.

Relation Determination and Database Abstraction

Short description:

Romeo asked about determining if a relation is many-to-many or one-to-many, which can be seen in the Prisma schema by declaring whether a field is a list or not. The name flag in the Prisma Migrate dev command is responsible for naming the migration. Auto-complete is the best way to see all the query params available, but the Prisma API documentation provides comprehensive information as well. Christian asked if Prisma can be implemented in a project using Mongoose and later changed to use Postgres. While Prisma abstracts over data sources, it's not intended to be a one-size-fits-all database abstraction. Generating models from an existing database can be done with the Prisma DB pull command, which runs introspection to populate the Prisma schema based on the database schema.

Then another question from Romeo, how will we know that the relation is many to many or one-to-many? That you can pretty much directly see inside of the Prisma schema, right? Because inside of the Prisma schema, you declare whether a field is a list or not. So in this case, on one side, I declared that there is a list. And on the other side, I declared that there is no list but only a single field or a single entry. And that's why we can know that it's a one-to-many. If we wanted to make this a many-to-many where one post could have multiple authors which would be a valid use case, I guess, I could do this. And in this case, we would have a many-to-many relation where we wouldn't store an author ID anymore because Prisma now under the hood would create a relation table or a join table for you to take track, to keep track of all the related records.

Another question about the name flag in the Prisma Migrate dev command. So the name flag is responsible for naming the migration. So it's what's being appended to the migration directories that are being created on your file system when you supply this value.

Next question is auto-complete the only best way to see all the query params available? If you ask me, yes, it's the best way. But it's not the only way. So we have pretty extensive API documentation for Prisma as well. So if you go to our docs and you check out the Prisma Client API reference, you can see under the model queries for each kind of query for find unique or the options that are being provided information about the return type. So very comprehensive documentation that lists everything that you can do with all of these queries.

Let's see. More questions, one more question from Christian. Let's say I have an sjs project and it uses Mongoose. I'm thinking of changing it to sometime in the future to use Postgres. Can I implement Prisma on my project? So I'm using MongoDB. Maybe when the time comes, I'll just change the data source to Postgres from the Prisma schema. That's a very good question. So the question basically is if Prisma, if the Prisma schema abstracts over the data sources in a way that you can always to swap out the underlying database and continue working with the same schema. If I understand your question properly, I think that's their question, otherwise feel free to correct me. So the answer to this is, no, you cannot do this. And there is actually like quite a good reason. I think why this is not the case and why this is not possible. The Prisma schema is not intended to be a one size, like one size fits all database abstraction. We certainly acknowledge that each database and each type of database comes with their own kind of strength and weaknesses with their own features. And we want to make sure that we support all the features of a database when we build a Prisma connector for it. And specifically, like as an example, why this is not possible, if we look at SQLite, for example, which is a pretty straightforward database in terms of the data types that it supports. And for example, in SQLite, you don't have support for enums. But enums are a crucial part of data modeling when you're working with Postgres or MySQL. So on these other databases, enums are supported. That means that now here in my SQLite Prisma Schema, I am not able to define an enum, but if I were to change this to Postgres where these are supported, then I would be able to use an enum here. But if I change this again back to SQLite, it's not possible. So we try to still make sure that no matter which database you use, you can make use of all the underlying features of the database. And in your example, specifically Christian, where you're thinking about moving from MongoDB to a relational database, this is also a lot more complicated than, of course, in terms of how you modeled your data in the first place in MongoDB. If you're using, for example, a lot of embedded documents, there is not really a good way to represent these in a relational database. I guess on Postgres you could use the JSON column, so that might be a way how you can migrate the data. But in general, it's not a use case, at least that we're optimizing for, but if your Prisma schema only uses kind of pretty straightforward features that you also find in all other databases, then I guess it's possible, but it's not really a use case that we're necessarily optimizing for. Is there a way to generate models from an existing database such as SQLite auto for SQLite? I'm not familiar with SQLite auto, but I think if I understand your question correctly, then yes, there is such a way, we call it introspection. And it basically is a command in the Prisma CLI, it's called Prisma DB pull that runs the introspection. And if you run this against a database, then it will read the database schema. So it will look at the tables, will look at the columns and it will populate the Prisma schema for you so that you don't have to write the Prisma models by hand if you already have an existing database. Yeah, cool. Yeah, it's like super helpful, like the Prisma DB pull command. And in fact, this is also something that we're currently building even for MongoDB to make it easier for current Mongo users to get started. And of course, with MongoDB, it's a little bit more involved because you don't actually have a schema, right? It's like, it's not something that's being enforced by the database itself. So we're kind of hoping that the data that people have put into their MongoDBs is consistent. And then we're reading it out and deriving the model structures from the individual objects that people have in their databases.

Example of dbPol and Prisma Client Queries

Short description:

An example of how dbPol works is shown by populating the Prisma schema with models that adhere to the data source. Relation fields are virtual fields in the Prisma schema that provide a nicer Prisma client API when working with relations. Pratik asked about defining content as a string and its limit, which depends on the underlying database. SQLite, for example, uses the text data type, while other databases like Postgres and MySQL allow you to specify the length. Issues with null constraint violation on the author ID field can be resolved by making the field optional. Problems with the new model not showing up in auto-complete can be fixed by restarting the TypeScript server in VS Code or deleting and reinstalling node modules. The find unique method in Prisma helps to find a record in the database by any unique property, including the ID. In the next lesson, you will learn how Prisma Client integrates into a REST API or GraphQL API.

An example of how dbPol work, so of course, what I can actually do here is to quickly show it. So assume I have an empty Prisma schema here, so far I only defined the data source. And if I now want to populate the Prisma schema with the models that adhere to the data source, I can just copy and paste it into the data source. That adhere to the tables that I already have in the database, I can run npx Prisma dbPol, it reads the structure of my database and creates the models for me.

The only thing that you should be aware of is that these relation fields, because they don't actually exist on the database, right? These are virtual fields that you only put in the Prisma schema to have a nicer Prisma client API when working with relations, but these don't exist in SQL. It will not infer any smart names for these, but only name them according to the type. So you probably often want to rename these after you ran a Prisma dbPol to make a little bit more sense and to fit the casing of your models otherwise.

All right, there is a question from Pratik about defining content as string and what's the limit for a string and int types? And this question is interesting because it cannot be answered just by looking at the Prisma schema because the Prisma types are only abstractions over the underlying data types of the database. So in this case in particular, if you're looking at the post, we see that this was just created as a text under the hood. So now you would have to go and look up in the SQLite documentation, how much characters are allowed for the text data type. And in fact, I recently learned this about SQLite. So it's special to SQLite that there are no varchars of a specific link, of a specific size. So if you use a SQLite database and you want to declare a column as varchar of like 30 characters or something like this, and then you run a migration, SQLite under the hood, well, actually also, it will accept the command because it accepts varchar as a keyword. But under the hood, it will just create a text for you. A text data type. For Postgres on the other hand, and MySQL and other databases, you can enrich the data types that you're declaring here in the Prisma schema with native type attributes that you can access like this. DB in this case is the name of the data source. And here you can now specify, for example, how long the title is supposed to be. And that way the constraint will be enforced when you try to create a post record in the database that has more than 256 characters.

All right, I think that all the questions from the chat are cleared. I would already suggest to move on with the next task, maybe a quick show of hand again, although, wait, I cannot hit anything with this. Okay, so quick show of hands again, who has already done with all. Quick note for those of you that ran into the issues of the null constraint violation on the fields author ID, I'm supposing, I'm guessing that you forgot the question mark right here. And that way you're making this field required. And what Prisma Migrate is trying to tell you here is that you're trying to add a required column to the database, but that would violate the consistency or the integrity of your data because you already have a post record in the database that has no field for author ID yet. So first you would have to go and update all the records that you have already in the database, set a value for them, and then you could run this migration. But the easier way is to just make this optional for you to circumvent this problem. I think that should be the issue, let me know if that's not.

Okay, issue from Derek about the new model not showing up an auto-complete. But you can execute QRIS against it. So that's probably then an issue with your VS code setup. I have seen some issues with that in the past and what usually helps is to restart the TypeScript server inside of VS code. And the way how I usually do this I use the, I like the command palette with command shift P and then I can type restart TypeScript. Why did they remove this? Maybe they renamed it since I last used it, restart dev server. No, interesting. I don't know why this not working anymore, why this is not possible. What else you can do is just to try and delete node modules and reinstall like node modules because that will also regenerate your client and maybe your Prisma types would be picked up then. So that's another thing that you could try, just the lead node modules run NPM install again and that should then hopefully fix your types. But yeah, it's an issue with kind of your VS code setup. Other question, do we always have to give a unique ID to find an entity in find unique? Yes, that's the entire point. Like find unique is a method that helps you to find a record in the database by any unique property. And as I mentioned before, that could either be one where you use the at unique attribute or also just the ID because it's implicit that this is unique. If you just want to have a random record, you can use find first, and that's when you don't have to provide a unique field.

All right, I would suggest that we move on with the next task or with the next lesson. And that being said in the next lessons, by the way, you will also again, write Prisma Client Query. So it's not the end of the world. If you didn't get through all the Prisma Client Queries here, you will now basically learn how Prisma Client integrates into a REST API or into a GraphQL API, kind of how it fits in. And for that, you are going to write Prisma Client Queries again. But instead of running them inside of a script, you'll add them in REST API routes and GraphQL resolvers. So let's go back to the overview page and move on to the next lesson.

Setting up REST API and Testing

Short description:

In this lesson, we will set up the REST API by following the provided instructions. We will reset the project, remove migrations and database files, and reinstall the necessary dependencies. The Prisma schema includes new fields for created at, updated at, and view count. The npx prisma migrate dev command will run the migration and seed the database. The tasks for this lesson are marked as todos in the index.ts file. We can use the REST client extension in VSCode to test the API requests. The Express server can be started with the NPM run dev command. The users query will return all users, and we can test this using the test HTTP file. We can also create a new user by implementing the create query. The incrementing of the view count for a post will also be demonstrated.

REST API. And let's first go and follow all the instructions for the setup. So here I just provided a number of commands that just make it easy for you to switch over to the new lesson because we're going to work in the same project the entire time. And I prepared kind of the starter kits for Lesson Three and Lesson Four in different branches of the same repo. So first, you can just stash your current work and reset everything that you've done. Then you can check out the REST API branch. Actually, I'll run these one by one. Taking out the REST API branch, I'll talk about the data model in just a bit. And we also start from scratch with our database. So we are removing the migrations, we're removing our SQLite database files, we're removing all the node modules and reinstalling them. And that being said, let's quickly look at the packaged JSON file and see what kind of dependencies we have in this project. So it's very straightforward. We only use the Prisma client and Prisma dependencies that we had in the previous project already. And then we add Express and the types for Express, types for node, TypeScript node and TypeScript because we're using TypeScript here. Oh, and actually I was wrong when I said that we wouldn't be using the seeding workflows because I did configure the seeding here so that each project we already start with some data in the database. But before we do that and before we run that, let's take a look at the Prisma schema in this one. it's very similar to the Prisma schema that you were using before. So we have the user and the post records. And then we have two new fields here created at and updated at that are being maintained at the database each also with default values. So in this case Prisma is always going to generate the current timestamp to keep track of when a record has been created. And also this updated at will be invoked every time a record is being updated and write the current timestamp to keep track of the last update of every record. And then we also add one new field that's called view count. It's an integer and it starts at zero and it's used to keep track of how many people have viewed a particular post in our app here. For the setup again, let's run the npx prisma migrate dev command. And one thing to note here is that under the hood, this command is also invoking the prisma dbseed command. And the dbseed command in turn is looking at the package.json file and it checks what I have defined as my seed command here. And in this case, it just executes a seeding script. And the seeding script is just some random data for us to get started with for this task. So if I now open this in Prisma studio, I see that I start with a user table with three user objects, four post objects. And I can actually also navigate and change the relations in here. One of the very nice features about Prisma studio, how it handles the traversal and the configuration of relations among your models. But let's go back to the Notion Document and to your tasks. So for this lesson, you will find all of the tasks marked with todos inside of the index.ts file here. And that file has a bunch of comments already that are marked as todo, and you can go through them and just figure out what's the right Prisma Client Query based on the instruction that you see here again in the Notion Document. Collapsing on the solutions here. All right. So, and the way how this is going to work, by the way, I created a couple of test HTTP requests for you that you can use if you install the REST client and extension inside of via code. This is super handy when you need to test like REST APIs, and you don't want to leave VSCode for that. So, as an example, I'm going to show you how to do this with the users query that's just supposed to return all users. So, I'm using the same FindMany query that we were using in the script before. And now I can start the Express server, again, also with the NPM run dev command and the server's now ready at port 3000. And if I go to slash users, then it will invoke the users route that I just implemented and fetch all the users from the database and return them. But to make this even nicer, you can use this Tesh HTTP file and you can also test this right inside of VSCode here. So, if I click on send request, I also see the HTTP request that was fired and the response that I'm getting a return with the data that I'm expecting a little bit nicer, a little bit more nicely formatted than in the browser. I could also already try to send this post request to create a new user, but because I haven't implemented that route yet and I'm also not returning anything, this is actually just running into kind of an infinite loop here. So, let me first go ahead and implement this query to create a new user based on the name and email that I receive here npm run dev, start the server, and I can go back to the test HTTP. Now I click send request again and I see that the new user was created, same problem as before in the script that I showed you, if I send this particular, this same requests here one more time, it again fails with the unique constraint violation on the email field because I haven't changed the email value and I was trying to create a second record with the same email, but if I do this and send the requests again, then I created a second entry just with a slightly different email. Let's see what other tasks there are. And then you will get some time to work on it by yourself. Actually, I want to show you this particular one, the incrementing of the view count of a post and how that's done.

Incrementing Views of a Post

Short description:

To increment the views of a post by one, an atomic operation is used in Prisma. By providing the post ID and using the update query, the view count can be incremented. After restarting the server, sending a request to the API will increment the view count by one.

For that, I'm using the app dot put, at the put method here, or function call. And the route is at post slash ID slash views. So what I know is I want to increment the views of the post with this ID that we already extract from the request params. And I want to increment it by one. And the way how to do that in Prisma is by using an atomic operation, atomic number operation to be precise. And again, I'm just using the autocompletion here. I want to update the post and I provide the ID. And now I can say, I want to increase the view count and increment it by one every time that this is being one. I think I actually have to do this. Because it comes out as a string, but it expects a number here, so that should work. I'm stopping the server and restarting it. And now I can go into my test.http file again, and send this request. And you can see how on the right side, the view count is incremented by one every time I send this request to the API.

Implementing Prisma Client Queries

Short description:

In this task, you will have 20 minutes to implement Prisma client queries and test them in VS Code. GraphQL is an alternative way to communicate with an API server from the front-end. It allows developers to send requests to the server, which performs logic, retrieves data from the database, and returns it to the client.

Okay, that's it for this task, for this lesson and the walkthrough. So now you have say 20 minutes again to implement these Prisma client queries yourself and test them inside of VS Code directly. So what GraphQL basically is, it's an alternative way to talk to an API server from the front-end. So even though it has the name QL, so query language in the name, it's not actually database technology, but it's an API technology. And it's similar to like rest APIs in that it lets a front-end developer or a mobile developer send a request to an API and then the application server is going to perform some logic, retrieve some data from the database and return that to the client.

Overview of REST and GraphQL APIs

Short description:

With REST, you have different endpoints and send various HTTP methods. However, with GraphQL, there is only a single endpoint where front-end developers send queries, eliminating the need to aggregate data from different endpoints. The GraphQL API setup involves stashing previous work, checking out the GraphQL API branch, removing migrations and databases, and reinstalling dependencies. The project's package.json file contains additional dependencies, including Apollo server, GraphQL, and GraphQL scalars. The code is located in index.ts, and running the server allows exploration of the GraphQL API in a playground. The defined schema outlines the available operations, but the lack of implemented resolvers results in errors when sending queries. Each operation in the schema requires a corresponding resolver function to fetch the data. The Prisma Client instance is accessible through the context, enabling auto-completion and interaction with the database.

With REST, you typically have a situation where you have a number of different endpoints, right? So in the example that we were just using ourselves, we have all of these different endpoints here. We have a user's endpoint, a signup endpoint, a post endpoint, post ID views endpoint. So we have all of these different endpoints and we send different kinds of HTTP methods to these endpoints. So get requests, post requests, put requests and you also have delete requests. So you have other kinds of requests that you can send to these REST API routes.

And with GraphQL, it's not the same. With GraphQL, your API server only has a single endpoint and your front end and mobile developers, they send GraphQL queries to that single endpoint. And that makes a lot of the things that front end developers usually have to deal with in their work such as aggregating data from different endpoints or over-fetching and under-fetching data. A lot of these problems that front end developers have to deal with makes these problems obsolete because GraphQL lets you very precisely define what data you actually want to have from the server and from the database as a front end developer. So that's kind of the high level overview.

For the next lesson, this is the GraphQL API. I'm going to run through the setup code again. So again, we're stashing everything that we worked on before. We're checking out the other branch with the GraphQL API. We're removing our migrations and database and also Node modules and re-installing them. The data model is the same as in the previous lesson for the REST API, so no surprises this time. And to continue our setup, we run npx Prisma Migrate Dev again, and we're feeding the same data again as well. So let's take a look at the project. Here is the package.json file with a few more dependencies this time. So we have Apollo server, GraphQL and GraphQL scalars as dependencies, and then a few more that are needed to get this project running. Again, all the TypeScript dependencies here. And then all the code again is located in index.ts. And in fact, we can already go ahead and run the server, start the server here, and then open a GraphQL playground, which allows me to explore the GraphQL API here.

And at the moment I can already see what kind of queries are available because the schema for my GraphQL server is already defined. The schema is defined right here and that defines all the operations that I can send to my GraphQL API. And here in the documentation, the playground, you basically see what operations you have defined in the schema. However, if I start sending queries now, if I would want to retrieve all the users and the IDs and the names of them, then I get an error and that's because the resolvers are not yet implemented. The resolvers are right here for each operation in the schema that we have defined. We have to define a corresponding resolver function that's responsible for fetching the data for these resolvers, for these operations. So starting with the all users query, we would go in and we can say, return Prisma. And actually, we have the Prisma Client instance attached to the context here. So in order to get auto completion, we have to use the context.first here. Text is our Prisma Client instance.

Implementing GraphQL API and Resolvers

Short description:

To continue the setup, run npx Prisma Migrate Dev again with the same data. The package.json file includes additional dependencies like Apollo server, GraphQL, and GraphQL scalars. The code is located in index.ts. Start the server and open the GraphQL playground to explore the API. The resolvers for the defined operations in the schema need to be implemented. Once the resolvers are implemented, you can see the users in the database. Nested queries can be used to retrieve additional data, but type resolvers need to be implemented for relation queries. The implementation follows a straightforward pattern. The server uses post requests for GraphQL APIs, with the query included in the body of the request. The GraphQL playground can be accessed at localhost:4000.

And to continue our setup, we run npx Prisma Migrate Dev again, and we're feeding the same data again as well. So let's take a look at the project. Here is the package.json file with a few more dependencies this time. So we have Apollo server, GraphQL and GraphQL scalars as dependencies, and then a few more that are needed to get this project running. Again, all the TypeScript dependencies here. And then all the code again is located in index.ts.

And in fact, we can already go ahead and run the server, start the server here, and then open a GraphQL playground, which allows me to explore the GraphQL API here. And at the moment I can already see what kind of queries are available because the schema for my GraphQL server is already defined. The schema is defined right here and that defines all the operations that I can send to my GraphQL API. And here in the documentation, the playground, you basically see what operations you have defined in the schema. However, if I start sending queries now, if I would want to retrieve all the users and the IDs and the names of them, then I get an error and that's because the resolvers are not yet implemented.

The resolvers are right here for each operation in the schema that we have defined. We have to define a corresponding resolver function that's responsible for fetching the data for these resolvers, for these operations. So starting with the all users query, we would go in and we can say, return Prisma. And actually, we have the Prisma Client instance attached to the context here. So in order to get auto completion, we have to use the context.first here. Text is our Prisma Client instance. And then we can just do the findMany as we did before. And again, I have to restart the server after I made a change. It's running. And now I can actually see which users are in the database because the resolver is now implemented. One thing to note though is that about GraphQL, a nice thing is that you can send nested queries. So I can do this to learn more about the posts that a user has published, but this isn't working yet. So we should actually already see data here, but we only see empty lists. And that's because the relation queries have to be implemented via these so-called type resolvers down here. And the implementation of these follow a pretty straightforward pattern that you don't really have to understand if you haven't worked with GraphQL before. So that's certainly beyond the scope of today's workshop. But the way how to implement them is just to find the author of the posts like this so you use I find unique query in here. You identify the current posts by the ID. And then in the end, you're using the Fluent API to invoke that author. And this is the same for the other way around, except that here you're using user and posts, and that's the pattern how you always implement these type resolvers with Prisma. You kind of have to learn that once and then you can apply that everywhere. Sorry, I accidentally inserted a string here. Okay, I'm stopping the server, restarting it. And now if I send this nested query, I can actually for each user, I can actually see what posts they have published already. Very cool, that's pretty much it for the walkthrough again of this part. I will give you about 20 minutes again to work on these lessons yourself. And then you, we are going to go ahead and wrap up the workshop for today. Excuse me Nicholas and how is it showed that we are using post requests for get requests? Yeah, it's a really good question. In this case, actually we are always using post requests because that's how GraphQL usually works is that you send a post request to the GraphQL API to the GraphQL API. And in the body of that post request, you include the query. So if we are opening the developer tools here and we inspect the network tabs, or we see that, so we're sending post requests. And as the payload, we see that the query that's defined here in the GraphQL playground is included. Oops. Okay, I got it. Ah, don't sync. Yeah, and you can access the playground here at localhost 4000. There was one question. Any idea why the autocomplete isn't working on the GraphQL branch anymore? Also on the context object previously, it worked just fine. That's a good question.

Generators and Choosing Prisma as an ORM

Short description:

The concept of a generator in Prisma is interesting and distinguishes it from other ORMs. Generators are functions that are invoked when the npm prisma generate command is called. They can be used to build custom generators or use existing ones provided by the community. For example, the prisma ERD generator visualizes entity relationships in a database schema. Prisma offers integrations with frameworks and libraries like type GraphQL, which generates CRUD resolvers. When choosing a database library, you need to decide if you want to work with SQL queries directly or use higher-level abstractions like Prisma. Plain database drivers require writing SQL queries, while ORMs like Prisma provide a more intuitive and type-safe way to interact with the database.

So it should work on the context object as long as it's defined as the context type here. Because on the context type, we define or we define the interface with a field called Prisma that's of type Prisma client. And that way it should work. And I don't really know why it doesn't work for you. I am sorry. If you want to get the auto completion, I mean, you don't actually have to use the Prisma client instance via the context. But what you could also do is just inside of your index.ts file and you could go and instantiate Prisma client like this and then just use the auto completion like this again. But in GraphQL it's kind of good practice to include any objects or anything thing that all the result that all the resolvers need access to inside of the concept inside of the context object. So as a best practice that should be done but I guess for the demo project today it's not super relevant how you do it.

All right, everyone are there any more questions about Prisma or the workshop today. I slowly want to start wrapping it up. Now of course you can finish everything on your own time. All the solutions are in the notion document anyway. So as long as you have access to that you basically have access to all the resources that you needed for this workshop. And there are also again the contact details how to reach me as included in the notion document as well.

There was one question about the generator in the very beginning of today's workshop. And I quickly wanted to circle back to that actually because the concept of a generator is actually really interesting I think. And also again, distinguishes Prisma from other ORMs. Basically a generator is a function that's being invoked when somebody calls the npm prisma generate command. Now you haven't actually used this command today because just like the dbc command, it gets called under the hood when you run prisma migrate dev. So that's why you never had to explicitly run this command by yourself. But if you invoke it, then what prisma does for you, it invokes all the generator blocks under the hood and invoking a generator block means that it invokes the function that's associated with the provider. And the main one that you typically use for that is just the one for prisma client that generates the data access library that we have been using today. But the cool thing about these generators is that you can also build your own generators and we have a whole section in our documentation in the section about generators that lists a number of existing generators that have been built by the community. So for example, let's try the prisma ERD generator. I haven't done this in a while, but I hope that this is functional. So ERD is a certain kind of diagram to visualize the entity relationships in your database schema. And so it's the prisma ERD generator. And if I run npx prisma generate again. Actually, first I have to install the generator in my project. Otherwise it can't be invoked. And we have also integrations for existing frameworks and libraries. So for example, there is a type GraphQL prisma generator that will generate all the CRUD resolvers that you need for a CRUD API with a type GraphQL, which is really handy. Oops, not again, npx prisma generate. So, let's see what it looks like when it generates the ERD, the entity relationship diagram, generated entity relationship diagram as an SVG file. Okay, that's an SVG, is there, I don't know. Can I, what's the fastest way to, Visualize an SVG actually. So that's what's being generated from this Prisma ERD generator. And it's basically so like these generators are basically tools that look at your current Prisma schema and they somehow transform or use the input from the Prisma schema, your models, to turn them into something else. And that could be resolvers for GraphQL APIs that can be diagrams, it can be like validations using the Zot library. So a lot of different things that are already available here but it's really up to you what you want these generators to do and build your own one after all. Okay, let me see if there have been new questions. And a few sentences, why should we use Prisma as an ORM in favor of other solutions? Okay, that's an interesting question that I can quickly speak to. So first and foremost, when you're picking a database library for your project, you first have to decide if you want to pick a database library where you in the end still have to create SQL queries. So you can use plain database drivers like NodePG, for example. That's a plain driver where you instantiate a database client like this. And then you just submit SQL statements to this client that you write as strings or you use a query builder like Connect JS where in the end you're still constructing SQL queries but by calling functions. So that's already a little bit closer to what we do with Prisma, but in the end you still have to know and be familiar, intimately familiar with SQL to use this. And if you don't wanna do this, then you can use higher level abstractions, these so-called object relational mappers, ORMs. And in the TypeScript space and Node.js space, there are really two that are the most popular at the moment.

Comparison with SQLize and TypeORM

Short description:

Prisma offers a better data modeling experience compared to SQLize and TypeORM. The Prisma schema serves as the single source of truth for your database and application models, making it straightforward and intuitive to query your database. Prisma also provides strong TypeScript support, allowing you to figure out queries using auto-completion. Additionally, Prisma offers stronger type safety guarantees than TypeORM, even when selecting partial models or including relations.

One is called SQLize and then TypeORM. And we have comparisons for both SQLize and TypeORM in our documentation. So if you're curious how Prisma compares against these, you can also go to our documentation and check out the comparing Prisma section here against TypeORM and SQLize.

The short story, why I would recommend Prisma over TypeORM and also the main benefits that we hear from our users compared to these libraries is the way how you do data modeling in Prisma is much nicer, much better experience. And the Prisma schema as the single source of truth for your database and for your application models, then the generated API and how straightforward and intuitive it actually is to query your database where in SQLize or TypeORM, because they also don't have very strong TypeScript support, of course, TypeORM is a little bit better there than SQLize, but you'll find yourself often looking up API documentation to figure out what a certain query has to look like with each of these. And with Prisma, that's really not the case. You can figure out most of the queries just by typing and using the auto-completion.

And another thing actually is the type safety and the type safety guarantees that Prisma can provide. And we have a comparison in that regard with TypeORM, which otherwise is probably the most type safe ORM in the TypeScript ecosystem. Certainly a lot more type safe than SQLise. And here we're explaining various scenarios in which Prisma can provide stronger type safety guarantees than TypeORM chem. For example, when you only select partial models or when you include relations, then this is always strongly type with Prisma through some very interesting TypeScript magic that we're doing under the hood. You will see that all of your Prisma client trees, even if you include relations, even if you select only specific fields will always be strongly typed. All right. I think that's it.

Watch more workshops on topic

GraphQL Galaxy 2021GraphQL Galaxy 2021
140 min
Build with SvelteKit and GraphQL
Top Content
Featured WorkshopFree
Have you ever thought about building something that doesn't require a lot of boilerplate with a tiny bundle size? In this workshop, Scott Spence will go from hello world to covering routing and using endpoints in SvelteKit. You'll set up a backend GraphQL API then use GraphQL queries with SvelteKit to display the GraphQL API data. You'll build a fast secure project that uses SvelteKit's features, then deploy it as a fully static site. This course is for the Svelte curious who haven't had extensive experience with SvelteKit and want a deeper understanding of how to use it in practical applications.

Table of contents:
- Kick-off and Svelte introduction
- Initialise frontend project
- Tour of the SvelteKit skeleton project
- Configure backend project
- Query Data with GraphQL
- Fetching data to the frontend with GraphQL
- Styling
- Svelte directives
- Routing in SvelteKit
- Endpoints in SvelteKit
- Deploying to Netlify
- Navigation
- Mutations in GraphCMS
- Sending GraphQL Mutations via SvelteKit
- Q&A
React Advanced Conference 2022React Advanced Conference 2022
95 min
End-To-End Type Safety with React, GraphQL & Prisma
Featured WorkshopFree
In this workshop, you will get a first-hand look at what end-to-end type safety is and why it is important. To accomplish this, you’ll be building a GraphQL API using modern, relevant tools which will be consumed by a React client.
Prerequisites: - Node.js installed on your machine (12.2.X / 14.X)- It is recommended (but not required) to use VS Code for the practical tasks- An IDE installed (VSCode recommended)- (Good to have)*A basic understanding of Node.js, React, and TypeScript
GraphQL Galaxy 2022GraphQL Galaxy 2022
112 min
GraphQL for React Developers
Featured Workshop
There are many advantages to using GraphQL as a datasource for frontend development, compared to REST APIs. We developers in example need to write a lot of imperative code to retrieve data to display in our applications and handle state. With GraphQL you cannot only decrease the amount of code needed around data fetching and state-management you'll also get increased flexibility, better performance and most of all an improved developer experience. In this workshop you'll learn how GraphQL can improve your work as a frontend developer and how to handle GraphQL in your frontend React application.
React Summit 2022React Summit 2022
173 min
Build a Headless WordPress App with Next.js and WPGraphQL
Top Content
WorkshopFree
In this workshop, you’ll learn how to build a Next.js app that uses Apollo Client to fetch data from a headless WordPress backend and use it to render the pages of your app. You’ll learn when you should consider a headless WordPress architecture, how to turn a WordPress backend into a GraphQL server, how to compose queries using the GraphiQL IDE, how to colocate GraphQL fragments with your components, and more.
GraphQL Galaxy 2020GraphQL Galaxy 2020
106 min
Relational Database Modeling for GraphQL
Top Content
WorkshopFree
In this workshop we'll dig deeper into data modeling. We'll start with a discussion about various database types and how they map to GraphQL. Once that groundwork is laid out, the focus will shift to specific types of databases and how to build data models that work best for GraphQL within various scenarios.
Table of contentsPart 1 - Hour 1      a. Relational Database Data Modeling      b. Comparing Relational and NoSQL Databases      c. GraphQL with the Database in mindPart 2 - Hour 2      a. Designing Relational Data Models      b. Relationship, Building MultijoinsTables      c. GraphQL & Relational Data Modeling Query Complexities
Prerequisites      a. Data modeling tool. The trainer will be using dbdiagram      b. Postgres, albeit no need to install this locally, as I'll be using a Postgres Dicker image, from Docker Hub for all examples      c. Hasura
Node Congress 2023Node Congress 2023
109 min
Node.js Masterclass
Workshop
Have you ever struggled with designing and structuring your Node.js applications? Building applications that are well organised, testable and extendable is not always easy. It can often turn out to be a lot more complicated than you expect it to be. In this live event Matteo will show you how he builds Node.js applications from scratch. You’ll learn how he approaches application design, and the philosophies that he applies to create modular, maintainable and effective applications.

Level: intermediate

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
Top Content
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
Vue.js London Live 2021Vue.js London Live 2021
24 min
Local State and Server Cache: Finding a Balance
Top Content
How many times did you implement the same flow in your application: check, if data is already fetched from the server, if yes - render the data, if not - fetch this data and then render it? I think I've done it more than ten times myself and I've seen the question about this flow more than fifty times. Unfortunately, our go-to state management library, Vuex, doesn't provide any solution for this.For GraphQL-based application, there was an alternative to use Apollo client that provided tools for working with the cache. But what if you use REST? Luckily, now we have a Vue alternative to a react-query library that provides a nice solution for working with server cache. In this talk, I will explain the distinction between local application state and local server cache and do some live coding to show how to work with the latter.
Node Congress 2022Node Congress 2022
26 min
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Top Content
Do you know what’s really going on in your node_modules folder? Software supply chain attacks have exploded over the past 12 months and they’re only accelerating in 2022 and beyond. We’ll dive into examples of recent supply chain attacks and what concrete steps you can take to protect your team from this emerging threat.
You can check the slides for Feross' talk here.
React Day Berlin 2022React Day Berlin 2022
29 min
Get rid of your API schemas with tRPC
Do you know we can replace API schemas with a lightweight and type-safe library? With tRPC you can easily replace GraphQL or REST with inferred shapes without schemas or code generation. In this talk we will understand the benefit of tRPC and how apply it in a NextJs application. If you want reduce your project complexity you can't miss this talk.
Node Congress 2022Node Congress 2022
34 min
Out of the Box Node.js Diagnostics
In the early years of Node.js, diagnostics and debugging were considerable pain points. Modern versions of Node have improved considerably in these areas. Features like async stack traces, heap snapshots, and CPU profiling no longer require third party modules or modifications to application source code. This talk explores the various diagnostic features that have recently been built into Node.
You can check the slides for Colin's talk here.