Next.js and Prisma: Databases in Serverless Made Easy - Daniel Norman - (Next.js Conf 2021)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
- Imagine that you could build the next JS app with a database without having to worry about writing SQL, scaling or managing infrastructure. What would that look like? I hope that today's talk can give you a glimpse into the future of databases in Serverless made easy. I'm Daniel from the Prisma team. But first, let me begin with how we got here. Over a year ago, we launched Prisma Klein to general availability and Next Generation ORM for no JS and tyes grid that helps you build faster and make fewer error When working with databases. Since then, we've heard from thousands of developers about how Prisma is helping them build and evolve their data intensive apps rapidly. Today, there are more than 40,000 Prisma developers, many of whom using it with next JS. And this is no surprise, while Next JS makes app development fun and easy Prisma makes it databases fun and easy to use. Since releasing Prisma Client too in June last year, we've worked tirelessly to make Prisma even better. We released Prisma Migrate to general availability and Prisma Migrate helps you evolve your database scheme at every step of the development workflow from prototyping to production. We also expanded our range of supported databases, and we now support Post gris, MySQL, SqLite, Asia SQL, SQL server in general availability and Mongo DB and planetscale in preview. Finally, we also launched the Prisma data platform, which helps you stop, collaborate, and scale your project. This is all part of our vision to liberate data and enable teams to take applications from prototype to billing users scale without compromise on productivity, security or compliance. But, there was one issue that kept on coming up amongst Next JS and Prisma users. Using databases is tricky. Database connection management in Serverless was the main problem. One of the promises of Serverless is easy scaling with zero operational overhead of maintaining infrastructure. But the reality is that using databases in Serverless is tricky. Database connections don't scale as easily as Serverless functions do. Relational databases that can handle thousands of transactions per second, can have a hard time dealing with 30 concurrent Serverless functions connecting to it. And so, today's talk will be split into three parts. In the first part, we'll see how Prisma gives you the best DX when working with your database. In the second part, we'll see how Prisma is the perfect companion if you need to work with a database in the Next JS app. And finally, in the third part, you will learn more about our vision for the future of databases and Serverless. And this includes the Prisma data platform, the Prisma data proxy, and finally Prisma with Serverless at the edge. And so I'll keep these talk hands-on with real code samples. So let's get right in, Prisma the best developer experience for databases. There are three pillars that make Prisma so easy to use with databases. The first one is the Prisma schema, a declarative single source of truth, where you define your data model can be written by hand or populated by introspecting an existing database. The second is type safety and type safety is a way to ensure that all application code interacting with the database can only do so safely. For example, attempting to write to a non-existent database column will raise a type error that you can immediately see in vs code. Zero cost means that you don't have to define TypeScript types, like in most ORN. with Prisma, these types of generated for you. Moreover, the types that Prisma generates give you rich auto-completion unlike any other ORM. The third, and finally is cogeneration. And the idea here is that you should only need to write things once. Prisma, saves you time by order generating to artifact that you would otherwise have to write by hand. The first is the fully typed TypeScript client that is known as Prisma client. And the second are SQL migrations, which are generated for you based on changes in your Prisma schema. So let's see how all of these pillars work in action here. Here I have a very simple Prisma schema that defines a single model. With Prisma and model maps onto a database table. And this is a schema data model that will be used for a blog. And so what we're going to do now is we're going to do a couple of things. We're going to evolve this schema and then see how we can use that in the Next JS app. And so to start off, we're going to extend the functionality and extend this data model to include commenting functionality so that every blog post can have multiple comments associated with that. So I have vs code here with the Prisma vs code extension, which gives you auto completion and helps you when you're modeling your problem. So in our case, we want to define a comment model. We wanted to have an ID that will be the primary key. And we also wanted to auto increment, we are going to define a common field of type string. This will actually store the comments. And we also want to define the relation, and for the relation we're first going to define the foreign key. So I will call this post idea type int, and then I need to define the actual relation field that will tell Prisma how you can fetch those relations in Prisma client. And so for this, I'm going to name it "post of type posts". Now, if I use the format of prisoner, it'll automatically add the back relation and there we have it. So I'm going to rename this to "comments" so that it makes sense in terms of the fact that it's plural and there we have it. So we've just finished extending our prisoner scheme by adding a new model, which will be the basis for a new database table. And now we're going to use Prisma migrate in order to generate a migration so that the database schema is aligned with our Prisma schema. And so this is really as simple as the NPX Prisma migrate dev command. This will look at the changes in our Prisma schema, compare them with the database schema and generate the SQL based on this. And I'm going to call this migration "add comments", and then we have it. Our migration is being generated for us. And our database is now in sync with the schema. We also had Prisma client generated for us so that we can already access and interact with the database in the type safe manner, including this new comment table that has been created for us. So let's take a quick look at the migration and here we have it, creates a table and it adds a foreign key which references the post table. Okay. As a next step, we're going to define a seed script and a seed script is a way to populate your development database with some initial data that makes it easier to build and develop. So for this have already defined an initial file, which imports Prisma client. And in this main function, I'm going to use Prisma client in order to write a post with some comments to the database. So let's take a look at how that works. Equals await, Prisma dot, and you can already see how you get this reach. Auto-completion, I already have the two models that I've created in the prisoner schema, and this is all coming from the generated code that was automatically generated after we ran the migrate dev command. So in our case, we want to create a post. And here we have all of the different crowd operations that we can do in our case. We want to use create because we're creating a single post. and here too, you get auto completion and you can already see the squiggly lines. And this squiggly line is because we're missing the title and the excerpt, which we defined as required fields in the Prisma schema. And so, let's start with the X excerpt and we'll define a title. And you can see that the squiggly lines are gone because we already defined the required fields. And now we want to also create related comments and you can see how easy this is with Prisma using the auto-completion. We have these comments and here we want to create, and we're going to pass it in array and comment "Wow". If I create another comment and I pass a number to it, what I expect to get is a type error. And this is because we've defined this as type string in the prisoner schema. And so here, we're getting this type error to make sure that we're using the right type and there we have it. The final step, is to make sure that we've defined this seed script in the package, Jason which have already done, And you can see that here, this is the command. And so let's go ahead and run this seed script. And for this, I'm going to use the Prisma DB seed command. And there we have it. Our post and related comments have been generated, created for us in the database. Let's take a look now using Prisma studio and modern GUI for your database. What that looks like in the database, from the browser. To do this, I'm just going to use the Prisma studio command, which will start a server. And there we have it, our post and the two related comments. We can also go ahead to the comments and add a new one. And here we can pick the post that we want to relate it to and save it. And there we have it. So that was Prisma inaction. And let's just recap what we did. We extended our Prisma schema by adding the comment model, we then use Prisma migrate to evolve the database and to update the database schema. We then use Prisma client to define the seed script. We seeded the database with some initial data. And then finally we use Prisma studio in order to interact and view our data from the browser. In the next step, we're going to see how we can use Prisma with Next JS. Part two, next JS and Prisma. in this part, you're going to see all the ways that you can use Prisma to serve your data needs with Next JS. So this brings us to all the ways that you can fetch data with Next JS. And essentially there are three ways, at Bill Dime using Static Generation, with get Static Props. This is suitable for data that doesn't change often like a blog. You also have the option to fetch data at request time using Service-side Rendering with getserversideprops. This is really useful for highly dynamic data that you want fresh for every request. And finally, using API routes with client side fetching. And this is really useful if you want to extend your client's side functionality with some more data. And the good news is that you can use Prisma with all of these three approaches. So let's take a look at the code. Here we have the same schema that we've defined before and the Next JS app built and based on it. And here we have the index page that we can see here. And as you can see, I'm using get static props and I'm making a Prisma client call in order to fetch the posts ordered by ID in descending order, which will ensure that the most recent ones show up on the top. Also worth noting, that here I'm using the same type that is generated by Prisma as the type for the props. And this ensures that we have end to end type safety. So for example, if I tried to log one of the posts, I immediately get the same auto-completion as we get in the client's side. So that was our index page. And we also have the page to show individual blog posts. And for this we're going to show the server-side rendered version and the equivalent code, and here we're using get server type props which means that it will get rendered for every request. And here we're using the find unique because we want to get a single individual blog post. We're also taking the ID in the URL parameter and using that to narrow our query to an individual blog post. And you can also see how I'm also including the related comments ordered by their ID in ascending order, which means that we can in a single query Prisma client query, we can fetch both the posts and the related comments. Finally, we also have these lights functionality that allows you to like a page, and this is using API routes. And for this, let's take a look at what the end point looks. And so here we have this handle function and here we'll use the prisma.post update method in order to increment the number of likes by one. And so those were all the different ways that you can use Prisma to fetch your data. And I want to make a quick note about another optimization that you can do, and that is called Incremental Static Generation. And the idea behind Incremental Static Regeneration is that it's like a hybrid between service-side rendering and static generation. So the challenge is if you add a new blog post to the database, you now have to wait for the whole build to finish for that to be reflected. And if you want those changes to be reflected more quickly, you can rely on incremental static regeneration. The idea here is that you define a revalidate configuration option in the get static props. And what happens when a request comes in, it says whatever's in the cash, but in the background, it goes ahead and re renders as the page. And so that way you don't have to trigger a new build for every time something in your database changes. So let's go back and take a look at what that looks like in practice. And I'm going to use the index page because Incremental Static Regeneration is used for pages that define get static props. And really it's as simple as defining this revalidate and the number of seconds after which it'll regenerate when a request comes in. And so if I save that, that will ensure that the index page is always fresh with data from the database. So that was Incremental Static Regeneration and another great optimization that Next JS offers. And so to sum this up, Prisma can be used for all of your data fetching needs in Next JS. In the next part, we're going to start looking back at some of the challenges of Serverless and how we can solve them with the Prisma data platform. This brings us to the future of Serverless in this last part of this talk. The Prisma data platform. In this part, we're going to look back at some of the challenges of working with databases in Serverless and how the Prisma data platform can help you solve those. So for this, we have an ask me anything page that allows me to answer questions with voice. The page has been built with next JS, Prisma, MySQL, and we're going to see how the connection management problem arises. And so this is a very similar page in terms of the end points. You can, you can ask questions, you can react to questions by liking them. And also I can go ahead and record answers using voice right from the browser. I love Next JS and Prisma. And I can upload that and then it becomes visible to users. Okay. So let's take a look at the code for this. So for example, here I have the reaction's endpoint point that is called every time I click the like, and all it does is it increments the number of reactions. We also have the create question end point, which just creates a question in the database using Prisma, and also the get questions end point, which is used to render this page to show all of the questions on the initial load. And this is using service side rendering, I should say. Okay. So when does this problem arise? Well my database has a connection limit of 40 connections. That means that as many as 40 requests simultaneously can start causing the database to fail, which means that those requests will fail and the user requests will fail. In order to really emphasize this I'm going to run a load test. And I have to load test defined here. And essentially what this load test does is it makes three HTTP API calls to get the questions, to submit a question, and also to incriminate the likes on a single question. And so to run this, I'm going to open up my terminal and here I have it configured and it's pointing to the same URL as the deployed app. And what I expect to see when I run this is that many of the requests will fail. And this will happen as soon as the database connection is exhausted. And I also should say that I'm running 40 virtual users. That means that in this load test, it will be running this as if 80 users are making this request at the same time. And as we can see, only 90% of the get posts succeeded, 88% of the create question and 87 to like a question. And so our goal is to reduce this to zero because we're building production apps and we want them to run reliably. And so before we do that, let's take a quick look at this connection management problem with nice animation. With Serverless, each user requests starts a new Serverless function that opens a connection to the database. The problem is that during traffic spikes, you will quickly exhaust your databases connection limit. This leads to failed requests and lost data. That's why we've built the Prisma Data Proxy, which makes it a breeze to use databases in Serverless with Prisma. To manage service that sits between your Serverless functions and your database and handles database connection management for you. That way you can scale your app without crashing your database and without user requests failing. And today it's available in early access at clouddotprisma.io. Now that we have a solid understanding of the connection management problem with Serverless, we're going to import our project into the Prisma data platform and then create the Prisma data proxy and see how it can solve the connection management problem. And hopefully we'll do another load test and see how all of the requests succeed. So let's go and open up the onboarding page. I'm going to name this project AMA Prisma. I will import the repository and tell it to use the main branch and define the schema path. And we're going to use, I'm going to use the existing database and set it to the Frankfurt region. (drum roll) That's great. The connection string for the data proxy has been created for us, which means we can go ahead to the Versal configuration page and update the environment variables. So we'll copy that over. And I will open up my environment variables page for the project. And here you can see, we have this database URL and we want to look at the production one. And so we're going to go and change that to use the Prisma connection string and save that. And we will also need to update another one called the Prisma client engine type to tell it, to use the data proxy. And I should note at this point that by using the Prisma data proxy, you're actually making the Serverless function even smaller because the Prisma engine doesn't need to be packaged with it. Okay, So now that I've gone ahead and updated these environment variables, I can redeploy the app and let's look at the main one, the production, and we'll redeploy it. In this we'll use our new connection string. Now that our build completed, let's check it out. So let's first open up the app. And as you can see, it's working. It's also showing all of the questions from the load test, and let's run a load test now to see if it still runs perfectly, and if there are any failed requests. (bouncy music) And as we can see all of the requests succeeded. We just saw how the data proxy helped us solve this connection management problem. And I'm excited to share that you can try it out today. It's available in Early Access at clouddotprisma.io. And if you have any questions, be sure to go to ama-prisma .versal .app and drop your question. I'd be happy to answer those, but wait, there's more. Database connection management in Serverless is tricky. And as we saw the Prisma data proxy solves this problem, but the Prisma data plot platform offers much more than just a data proxy. Let's take a look at some of the functionality it gives us. So here we have the Prisma Data Platform. And what you can see now is the data browser and the data browser works very similarly to Prisma studio, except that it's hosted. And that it allows you to invite collaborators to view and also edit data in the database. So for example, here I can update the status of questions. I can look up the users in the database. In addition to all of this functionality, I also have the ability to write queries right from the Prisma Cloud Platform. And this is using this query console. So if I open up the query console, I can issue, for example, a query to find many AMS. And hearing this query I'm selecting just the idea and the question. And of course I could also use auto bi here. And even here you get the same auto-completion that you used to. So for example, we could order it by created at, in descending order. We could also order it based on updated dates in any order that we like. And so this is a bit more of the Prisma Data Platform. And of course, we have a lot more coming in store for you so stay tuned. Before I leave today, there's one more thing that I'm excited to share and that is I'm excited to announce that Prisma ORM is the first ORM to support Relational Databases in Versal edge middleware and CloudFlare workers. Here's the thing with Serverless runtime, as we saw connection management with databases can be challenging. And while the Prisma data proxy solves that problem, there's another problem, namely cold starts Initial requests to subtlest functions, take time to load, which leads to bad performance. Today, with the advent of vessel edge functions. I'm now excited to share that it changes because you no longer have to wait. And so, I've already implemented a middleware function in this AMA page to show the number of visitors. So for every request that is sent to this page, middleware function updates the number of visitors. Let's take a quick look at the code for this. So here we have this middleware function. And as you can see, the structure is a bit different. This is because it's using CloudFlare workers under the hood, which is a completely different runtime that doesn't rely on no JS. Here we make sure that if it's the root path, we continue, otherwise we just continue with the request. And if it is the root path, we'll take a hash of the IP and then store that in the visitor table. We also have the visitors end point, which lists account of the number of visitors from the last five seconds, sorry, the last five minutes. And so this allows us to provide this rich functionality with no compromises on load times. And in the near future, we expect to see both Server Side Rendering and Static Rendering to also support Versal edge functions. And so I couldn't be more excited to try all of this out. And I invite you to try this out. Support for Versal Edge is now in early access, and you can try it out today. Before we wrap up and I leave you, I'd like to summarize what we did today. In the first part, we look at how Prisma is the easiest way to work with databases. And the second part we learned about all of the different rendering techniques and ways that you can use Prisma with Next JS and how Prisma is your perfect companion if you're building database back next JS app. And finally, in the last part, we looked at some of the connection management problems and the future of Serverless and databases with Prisma. And so before we leave, I'd like to thank you for tuning in today. And I'd also like to thank our community for having been with us on this journey and trying out Prisma and providing us feedback. This wouldn't have been possible without you. And so I thank you very much. (upbeat music)
Info
Channel: Vercel
Views: 2,364
Rating: undefined out of 5
Keywords:
Id: gJoa5VRF0jY
Channel Id: undefined
Length: 27min 39sec (1659 seconds)
Published: Wed Oct 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.