In the startup world, if your business depends on software and its data, being agile and moving fast is crucial. Many changes will be needed over time, and your application should be able to handle those changes.
For products and applications, databases are essential. Over time, model and field changes will heavily affect your application, and you need to be sure that everything is working as it was before, despite the fact that your new features include database changes.
With this in mind, selecting technologies is often challenging due to the many libraries and technologies available in the world. At OAK’S LAB, we chose Prisma as the library to help us move forward quickly, safely, and reliably when we build our startups.
Prisma: The Node.js/TypeScript ORM
Prisma is an Object-Relational Mapping (ORM) tool for Node.js and TypeScript. It is type-safe and easily integrates into our stack for database modeling, migrations, and the connection between our applications and database.
Prisma takes away most of the repetitive work from us and gives us back more control over our databases. Plus, it has a great developer experience (DX) so we can focus on business needs and build startups quickly and safely.
4 Ways We Use Prisma
Since our startups require constant updates and feature releases, we use Prisma in many ways. Let’s take a look at four main features that Prisma provides, which help us on a daily basis: data modeling, out-of-the-box migrations, adding subscriptions to GraphQL, and reliably using the same database on multiple applications.
1. Data Modeling and Relations
When a project first starts or when it is picked up from where it left off, one of two things needs to be done in order to understand the application. You either create your database model or inspect the database. Here’s how we use Prisma in both cases.
- Creating your database model. Prisma allows you to create your models easily and understand them by providing a feature called Prisma Schema. Let’s look at an example. We will be modeling below for a small blog where users will have multiple posts, and each post can have multiple attachments.
By using Prisma Schema in this example, you can see how the models are connected and how each field is defined. All the definitions of fields have the database equivalent types underneath. You can even use types from the database directly.
- Inspecting the database. When it comes to working with already existing databases, Prisma will help you understand and create a schema from it with a feature called Introspection. Introspection reviews the current model in your database and creates a schema for you based on the model that’s there. This method becomes especially valuable if you are not using the Prisma Migrate functionality (see next point for more on that). Introspection will keep your model up-to-date with the current database so that you don’t have to sync changes manually.
For a more detailed look at Prisma Schema, visit the Prisma Schema reference page.
2. Out-of-the-box Migrations (Prisma Migrate)
You will often need many changes to the database in your application, and those changes should be the same in all environments you have. For example, if you are using other ORMs (like TypeORM or Sequelize), shipping changes require updates on your database relations and models. This means that you have to write all database changes yourself into a “.sql” file and make sure it applies to all environments.
Prisma helps you create these and ensures your changes can be applied to your database by providing a feature called Prisma Migrate. With Prisma Migrate, you don’t have to create “.sql” files by yourself. All you need to do is edit your Prisma schema, and Prisma will generate the migration file for you.
Let’s generate our migration with Prisma for the example we used above.
While generating the migrations, Prisma reviews your current database and warns you in case your changes cannot be applied. You will be able to move safely for each environment because those will be using the same migration history and same structure.
For a more detailed look at Prisma Migrate, visit the Prisma Migrate reference page.
3. The N+1 Problem
In OAK’S LAB, we also use GraphQL for our APIs, and GraphQL introduces the N+1 problem because it has a graph-like structure. This problem occurs when multiple relations are fetched and the database is queried more times than necessary. For example, if you are requesting 10 relations for a single entity in a GraphQL query, this might execute “1+10(since N=10)” queries on the backend if it’s not handled correctly. That is not efficient, and it will cause long response times.
To read more about N+1, here’s a great article from Shopify that looks at solving the N+1 problem through batching.
When Prisma is used appropriately with GraphQL, fetching relations is done as a batch (like a data loader) as opposed to being done one by one. Using Prisma for this approach removes the need for unnecessary calls to your database, thus saving time and resources.
To see how Prisma solves this problem, read about query optimization directly from Prisma’s documentation.
4. Middleware
While using database operations in your applications, you might want to log them, tweak them, or react to them. For example, if you want to use “soft delete,” doing this in multiple places across your codebase on each delete might be cumbersome. For this scenario, you can take advantage of Prisma Middleware to tweak all the delete actions that are happening on the database level. In addition, if you want to find out all of your queries’ execution times, you can add logging for the queries.
Prisma Middleware lets you intercept any query that you are running so that you can have the fine-grained, declarative control you need.
To see how it works and to look at more examples, read about Prisma Middleware directly from Prisma’s documentation.
In conclusion
This is just a highlight of the most important features provided by Prisma. There are definitely more that we utilize and love. We could talk about it all day long. Prisma helps us every day to create type-safe queries and changes, and it gives us comfort that we are using databases safely.
Prisma might not be the solution for everyone and for every problem, but right now it solves most of our common struggles across all our projects. If you are curious about the differences between Prisma and other ORMs, check out how it compares.
At OAK’S LAB, we mainly use TypeScript, Node.js, and GraphQL. And since Prisma is made for JavaScript and TypeScript, it integrates quickly and easily. While using Prisma, we don’t have to worry about the challenges that commonly arise on projects. We can focus more on creating features and building startups.
Using Prisma with these 4 features sums up why we love to work with the ORM. We can focus on what we need to build, and Prisma can take the extra work off our shoulders.
If you want to talk about Prisma and why we love it, you can find me on LinkedIn or send me an email at ugur.oruc@oakslab.com.