July 29, 2022

Database access on the Edge with Next.js, Vercel & Prisma Data Proxy

The Edge enables application deployment across the globe. This article explores what Edge environments are, the challenges that arise when working in Edge environments and how to access databases on the Edge using the Prisma Data Proxy.

What is the Edge?

Traditionally, applications would be deployed to a single region or data center, in either a virtual machine, Platform as a Service (PaaS) like Heroku, or Functions as a Service (FaaS) like AWS Lambda. While this deployment pattern worked fine, the problem this created was that a user located on the other side of the globe would experience slightly longer response times.

We — developers — attempted to fix this with the JAMstack architecture, where static assets, such as HTML, CSS, JavaScript, and images, would be distributed across the globe in a Content Delivery Network (CDN). This improved loading times — the Time to First Byte (TTFB) — of web applications, but if the application required dynamic data, e.g., from an API or database, the application needed to make another request for the data. This also worked fine. However, the side effect was that we also distributed loading spinners across the web.

We took this a step further and introduced Edge computing such as Vercel's Edge Network. The Edge is a form of serverless compute that allows running server-side code geographically close to its end users.

[Source] Cloudflare workers[Source] Cloudflare workers

Edge computing works similarly to serverless functions, without the cold starts because they have a smaller runtime. This is great because web apps would perform better, but it comes at a cost: A smaller runtime on the Edge means that you don't have the exact same capabilities as you would have in regular Node.js runtime used in serverless functions.

Check out this introduction to Edge computing by Fireship to learn more:

Traditional databases can't be accessed from the Edge

Edge environments only support HTTP-based connections. Therefore, connecting to traditional databases, such as PostgreSQL, wouldn’t be possible because these use long-lived TCP connections.

Another reason traditional databases can't be accessed from the Edge is because the applications are stateless. These applications don’t mix too well with traditional relational databases, which are stateful in nature. Every request to the application will create a new database connection, and in the event of a traffic spike, the database is likely to run out of database connections.

You can learn more about the challenges of database access in Edge environments, which is similar to serverless environments, in this article.

Database access on the Edge with the Prisma Data Proxy

The Prisma Data Proxy is a proxy server for your database that allows you to interact with your database over HTTP, manages a connection pool, and ensures database connections are reused.

It allows database access from Edge runtimes such as Vercel Edge Functions and Cloudflare Workers and a serverless environment.

Do single-region databases and the Edge fit toghether?

Edge computing is a fairly young, yet very promising technology that has the potential to drastically speed up applications in the future. The ecosystem around the Edge is still evolving and best practices for globally distributed applications are yet to be figured out.

At Prisma, we are excited about the developments in the Edge ecosystem and want to help move it forward! However, connecting to a single-region database as shown in this article is probably not the best idea for real-world applications today. As a best practice, we still recommend to generally deploy your database as closely as possible to your API server to minimize latency in response times.

While the architecture shown in this article might not cater to real-world use cases yet, we are excited about the possibilities that are opening up in this space and want to make sure Prisma can help solve the problems related to database access on the Edge in the future!

Demo: Database access on the Edge

Let's now take a look how to access a database from Vercel's Edge functions using the Prisma Data Proxy.

You can find the live demo of the application here and the completed project on GitHub.

The demo application that is used here is a random quote generator built with Next.js and styled with TailwindCSS. The application will take advantage of Next.js' Edge server rendering and Edge API routes to fetch data from a remote PostgreSQL database on every page refresh.

The final state of application you will be working on will resemble this:

The application contains a single model called Quote with the following fields:

// schema.prisma
model Quote {
id Int @id @default(autoincrement())
content String
author String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

Prerequisites

To successfully follow along, you will need:

Clone application

Navigate to your directory of choice and run the following command to set up a new Next.js project:

npx create-next-app --example https://github.com/ruheni/prisma-edge-functions/tree/starter prisma-edge-functions
Copy

Navigate into the directory:

cd prisma-edge-functions
Copy

The page and API Route are also configured to use Vercel’s Edge Runtime with the following configuration in both files:

export const config = {
runtime: 'experimental-edge',
}

Set up the database

You can use a free PostgreSQL database hosted on Heroku or Railway.

Once you’ve set up the database, update the .env file at the root of your project with the database’s connection string:

# .env
DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE"

With the DATABASE_URL environment variable set, apply the existing Prisma schema to your database schema using the prisma migrate dev command. The prisma migrate dev command will apply any pending migration in the /prisma/migrations folder against your database.

npx prisma migrate dev

Next, populate the database with sample data. The project contains a seed script in the ./prisma/seed.ts file and sample data in ./prisma/data.json. The sample data includes 178 quotes.

npx prisma db seed

You should see the following output:

Environment variables loaded from .env
Running seed command `ts-node prisma/seed.ts` ...
[Elevator Music Cue] 🎸
Done 🎉
🌱 The seed command has been executed.

Set up Prisma Data Proxy

Navigate to GitHub and create a private repository:

Next, initialize your repository and push your changes to GitHub:

git init
git remote add origin https://github.com/<username>/prisma-edge-functions
git add .
git commit -m "initial commit"
git push -u origin main

Note: Replace the <username> placeholder value with your GitHub username before pasting the value on your terminal.

Once you’ve set up your repository, navigate to the Prisma Data Platform and sign up for a free account if you don’t have one yet.

After signing up:

  1. Create a new project by clicking the New Project landing on the Create Project page
  2. Fill out your Project’s name and your GitHub Account details
  3. Select the Import a Prisma repository option and select the repository you just created under your account
  4. You can leave the default values for the Branch and Prisma schema path
  5. Once you’re satisfied with your changes, click Next

Next, you’ll connect the Prisma Data Platform to your database. Select Use my own database and paste your database’s connection string.

In the Prisma Data Proxy step, select the location closest to your database. If your database is secured behind a firewall, enable the static IPs option to connect to your database. You will get a list of IPs you can use to allow the Prisma Data Proxy to communicate with your database.

Once you’re done, hit the Create project button to finish setting up your project.

You should see a Deploy project page with a new connection string — a Prisma Data Proxy URL — starting with prisma:// after your project is created successfully. Copy this connection string and click Done.

Update your application code

Back in your project, rename the existing DATABASE_URL to MIGRATE_DATABASE_URL and paste the Prisma Data Proxy URL into your .env file as the new DATABASE_URL:

DATABASE_URL="prisma://{DEPLOYMENT_LOCATION}.prisma-data.com/?api_key={DATA_PROXY_API_KEY}"
MIGRATE_DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE"

The MIGRATE_DATABASE_URL variable will be used to apply any pending migrations during the build process. The package.json file uses the vercel-build hook script to run prisma migrate deploy && next build

Next, generate Prisma Client that will connect through the Prisma Data Proxy using HTTP:

npx prisma generate --data-proxy

Then, navigate to lib/prisma and update Prisma Client’s import from @prisma/client to @prisma/client/edge to be make it compatible with edge environments:

// lib/prisma.ts
-import { PrismaClient } from "@prisma/client";
+import { PrismaClient } from "@prisma/client/edge";

Test the application locally

Now that setup is done, you can start up your application locally:

npm run dev

Navigate to http://localhost:3000, and this is what it might look like at the moment.

The quote you will see might be different because the quote is selected randomly. You can hit Another one 🔄 to refresh the page with a new quote.

You can also navigate to http://localhost:3000/api/quote to get a random quote in JSON format.

Deploy the application

Commit the existing changes to version control and push them to GitHub.

git add .
git commit -m "update prisma client"
git push

Navigate to Vercel and import your GitHub repository.

Give your project a name and open up the Environment Variables toggle and fill out the following environment variables:

  • MIGRATE_DATABASE_URL: the database’s connection string
  • DATABASE_URL: the Prisma Data Proxy connection string
  • PRISMA_GENERATE_DATAPROXY: true

The PRISMA_GENERATE_DATAPROXY environment variable ensures that Prisma Client for Data Proxy is generated in the build step.

Finally, click Deploy to kick off the build:

Congratulations

Once the build is successful, you should see the following:

Click the Visit button to view the deployed version of the application.

Back on the Vercel dashboard in the Overview tab, click View Function Logs. Next, select the “index” function. You will see that your application’s runtime is Edge and the Region is Global.

Refresh the page in your application, and back on Vercel, you will see the request’s status logged.

Congratulations! 🎉 

Conclusion

The Edge enables instant application deployment across the globe, changing how developers think about application development and deployment.

The Prisma Data Proxy is one tool that enables developers to build and ship web apps requiring database access on the Edge.

The Edge is still in its early stages, with a few drawbacks. However, it's exciting to see how building web apps on the Edge will look.

Join the discussion

Follow @prisma on Twitter

Don’t miss the next post!

Sign up for the Prisma newsletter

prisma_logo

© 2022 Prisma Data, Inc.

Newsletter

Stay up to date with the latest features and changes to Prisma