The
Jamstack approach originated from a speech given by Netlify’s CEO Matt
Biilmann at Smashing Magazine’s very own Smashing Conf in 2016.
Jamstack
sites serve static pre-rendered content through a CDN and generate
dynamic content through microservices, APIs & serverless functions.
They are commonly created using JavaScript frameworks, such as Next.js
or Gatsby, and static site generators — Hugo or Jekyll, for example.
Jamstack sites often use a Git-based deployment workflow through tools,
such as Vercel and Netlify. These deployment services can be used in
tandem with a headless CMS, such as Strapi.
The goal of using
Jamstack to build a site is to create a site that is high performant and
economical to run. These sites achieve high speeds by pre-rendering as
much content as possible and by caching responses on “the edge” (A.K.A.
executing on servers as close to the user as possible, e.g. serving a
Mumbai-based user from a server in Singapore instead of San Francisco).
Jamstack
sites are more economical to run, as they don’t require using a
dedicated server as a host. Instead, they can provision usage from cloud
services (PAASs) / hosts / CDNs for a lower price. These services are
also set up to scale in a cost-efficient manner, without developers
changing their infrastructure and reducing their workload.
The
other tool that makes up this combination is Prisma — an open source ORM
(object relational mapping) built for TypeScript & JavaScript.
Prisma handles connections to the
database (including pooling) and database migrations. It can connect
with databases that use PostgreSQL, MySQL, SQL Server or SQLite
(additionally MongoDB support is in preview).
To help you get a sense of Prisma, here’s the some basic example code to handle the CRUD of users:
datasource db {
url = env("DATABASE_URL")
provider = "postgresql"
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
The Use Cases for Prisma
Armed
with a knowledge of how Prisma operates, let’s now explore where we can
use it within Jamstack projects. Data is important in two aspects of
the Jamstack: whilst pre-rendering static pages and on API routes. These
are tasks often achieved using JavaScript tools, such as Next.js for
static pages and Cloudfare Workers for API routes. Admitally, these
aren’t always achieved with JavaScript — Jekyll, for example, uses Ruby!
So, maybe I should amend the title for the case of Prisma in
JavaScript-based Jamstack. Anyhow, onwards!
A very common use-case
for the Jamstack is a blog, where Prisma will come in handy for a blog
to create a reactions system. You’d use it in API routes with one that
would fetch and return the reaction count and another that could
register a new reaction. To achieve this, you could use the create
and findMany
methods of Prisma!
Another
common use-case for the Jamstack is a landing page, and there’s nothing
better than a landing with some awesome stats! In the Jamstack, we can
pre-render these pages with stats pulled from our databases which we can
achieve using Prisma’s reading methods.
Sometimes, however,
Prisma can be slightly overkill for certain tasks. I’d recommend
avoiding using Prisma and relational databases in general for solutions
that need only a single database table, as it adds additional and often
unnecessary development complexity in these cases. For example, it’d be
overkill to use Prisma for an email newsletter signup box or a contact
form.
Alternatives to Prisma #
So,
we could use Prisma for these tasks, but we could use a plethora of
other tools to achieve them. So, why Prisma? Let’s go through three
Prisma alternatives, and I’ll try to convince you that Prisma is
preferable.
Cloud Databases / Services
Services
like Airtable are incredibly popular in the Jamstack space (I myself
have used it a ton), they provide you with a database (like platform)
that you can access through a REST API. They’re good fun to use and
prototype with, however, Prisma is arguably a better choice for Jamstack
projects.
Firstly, with cost being a major factor in Jamstack’s
appeal, you may want to avoid some of these services. For example, at
Hack Club, we spent $671.54 on an Airtable Pro subscription last month
for our small team (yikes!).
On the other hand, hosting an
equivalent PostgreSQL database on Heroku’s platform costs $9 a month.
There certainly is an argument to make for these cloud services based on
their UI and API, but I would respond by pointing you to Prisma’s
Studio and aforementioned JavaScript / TypeScript client.
Cloud
services also suffer from a performance-issue, especially considering
that you, as the user, have no ability to change / improve the
performance. The cloud services providing the database put a middleman
in between your program and the database they’re using, slowing down how
fast you can get to the database. However, with Prisma you’re making
direct calls to your database from your program which reduces the time
to query / modify the database.
Writing Pure SQL
So,
if we’re going to access our PostgreSQL database directly, why not just
use the node-postgres module or — for many other databases — their
equivalent drivers? I’d argue that the developer experience of using
Prisma’s client makes it worth the slightly increased load.
Where
Prisma shines is with its typings. The module generated for you by
Prisma is fully type-safe — it interprets the types from your Prisma
schema — which helps you prevent type errors with your database.
Furthermore, for projects using TypeScript, Prisma auto-generates type
definitions that reflect the structure of your model. Prisma uses these
types to validate database queries at compile-time to ensure they are
type-safe.
Even if you aren’t using TypeScript, Prisma also offers
autocomplete / Intelli-sense, linting, and formatting through its
Visual Studio Code extension. There are also community built /
maintained plugins for Emacs (emacs-prisma-mode), neovim (coc-prisma),
Jetbrains IDE (Prisma Support), and nova (the Prisma plugin) that
implement the Prisma Language Server to achieve code validation. Syntax
highlighting is also available for a wide array of editors through
plugins.
Other ORMs
Prisma
is, of course, not the only ORM available for JavaScript / TypeScript.
For example, TypeORM is another high quality ORM for JavaScript
projects. And in this case, it is going to come down to personal
preference, and I encourage you to try a range of ORMs to find your
favourite. I personally choose Prisma to use for my project for three
reasons: the extensive documentation (especially this CRUD page,
which is a lifesaver), the additional tooling within the Prisma
ecosystem (e.g. Prisma Migrate and Prisma Studio), and the active
community around the tool (e.g. Prisma Day and the Prisma Slack).
Using Prisma in Jamstack Projects
So, if I’m looking to use Prisma in a Jamstack project, how do I do that?
Next.js #
Next.js
is growing to be a very popular framework in the Jamstack space, and
Prisma is a perfect fit for it. The examples below will serve as pretty
standard examples that you can transfer into other projects using
different JavaScript / TypeScript Jamstack tools.
The main rule of
using Prisma within Next.js is that it must be used in a server-side
setting, this means that it can be used in getStaticProps
, getServerSideProps
, and in API routes (e.g. api/emojis.js
).
In code, it looks like this (example taken from a demo app I made for a talk at Prisma Day 2021 which was a virtual sticker wall):
As you can see, it integrates really well into a Next.js project. But you may notice something interesting: '../../../lib/prisma'
. Previously, we imported Prisma like this:
Unfortunately, this is due to a quirk in Next.js’ live refresh system. So, Prisma recommends you paste this code snippet into a file and import the code into each file.
Redwood
Redwood
is a bit of an anomaly in this section, as it isn’t necessarily a
Jamstack framework. It began under the banner of bringing full stack to
the Jamstack but has transitioned to being inspired by Jamstack. I’ve
chosen to include it here, however, as it takes an interesting approach
of including Prisma within the framework.
It starts, as always, with creating a Prisma schema, this time in api/db/schema.prisma
(Redwood adds this to every new project). However, to query and modify
the database, you don’t use Prisma’s default client. Instead, in
Redwood, GraphQL mutations and queries are used. For example, in
Redwood’s example todo app, this is the GraphQL mutation used to create a
new todo:
And in this case, the Prisma model for a todo is:
To trigger the GraphQL mutation, we use the useMutation
function which is based on Apollo’s GraphQL client imported from @redwoodjs/web
:
With
Redwood, you don’t need to worry about setting up the GraphQL schema /
SDLs after creating your Prisma schema, as you can use Redwood’s scaffold
command to convert the Prisma schema into GraphQL SDLs and services — yarn rw g sdl Todo
, for example.
Cloudfare Workers
Cloudfare
Workers is a popular platform for hosting Jamstack APIs, as it puts
your code on the “edge”. However, the platform has its limitations,
including a lack of TCP support, which the traditional Prisma Client
uses. Though now, through Prisma Data Proxy, it is possible.
To use it, you’ll need a Prisma Cloud Platform
account which is currently free. Once you’ve followed the setup process
(make sure to enable Prisma Data Proxy), you’ll be provided with a
connection string that begins with prisma://
. You can use that Prisma connection string in your .env
file in place of the traditional database URL:
And then, instead of using npx prisma generate
, use this command to generate a Prisma client:
Your
database requests will be proxied through, and you can use the Prisma
Client as usual. It isn’t a perfect set-up, but for those looking for
database connections on Cloudfare Workers, it’s a relatively good
solution.
Conclusion
To
wrap up, if you’re looking for a way to connect Jamstack applications
with a database, I wouldn’t look further than Prisma. Its developer
experience, extensive tooling, and performance make it the perfect
choice. Next.js, Redwood, and Cloudfare Workers — each of them has a
unique way of using Prisma, but it still works very well in all of them.
I hope you’ve enjoyed exploring Prisma with me. Thank you!
No comments:
Post a Comment