Deploy a GraphQL Server with Prisma

Martin Adams
Ecstatic Engineering
6 min readApr 11, 2020

Summary

In this essay I’ll walk you through how to create a GraphQL Server (using Apollo Server Micro) on a serverless platform (using Vercel), connect it (via Prisma) to a PostgreSQL database (hosted on ScaleGrid), and have the server connect to your client (a React app that uses Apollo Boost).

TL;DR: here’s a demo, and here’s the Github repo.

Introduction

But first, let’s do a quick big-picture overview of how an app usually works. For several decades now, applications have utilized a three-tiered model of how data is handled and presented to the end-user:

Recent advances in technology (Vercel’s NextJS platform used in conjunction with Prisma) have been able to securely merge the app and server into a single entity (via server-side rendering and data hydration at runtime), thus radically simplifying the web development approach.

However, there are many use cases for which the app and server need to remain separate, for example if you want to create an API that’s accessible by other apps and the general public. For this essay, we’ll keep them separate.

Caveats

There are a few caveats to keep in mind when creating a GraphQL server on a serverless platform. Here’s what Guillermo, Vercel’s founder, says about that:

A. Database Account Setup

  1. Create an account at ScaleGrid.io and create a PostgreSQL database with AWS as your cloud provider, and Dedicated Hosting. Go on to create a dedicated PostgreSQL deployment configuration of your choice. Be sure to Enable SSL. For the firewall, enter 0.0.0.0/0 as your IP CIDR; this allows your database to be reached from any IP address. Later, we’ll show you how to limit access to your database.

B. App Setup

  1. Next, clone and download this demo repository. It will function as the basis of your client and server.
  2. Install all dependencies (e.g. npm i or yarn — in this example we’ll mostly use yarn). You’ll notice a serverless entrypoint at /api/index.js , as well as an example database schema at /prisma/schema.prisma , some seed data at /prisma/seed, as well as the corresponding GraphQL schema at /graphql/typeDefs and example resolvers at /graphql/resolvers . The app itself is located at /src. The now.json file contains your environment variables, which we’ll need to set up later.

C. Database Setup

  1. In your ScaleGrid account, once your database cluster has been created, navigate to your PostgreSQL database and into the Users & DBs tab. Create a New User (e.g. admin) and create a new password. ScaleGrid requires the use of at least one special character in your password — since we’ll be using the password later in Prisma as part of a secure URL, we cannot use the character @ in our password (and possibly others). Uncheck both Can create DB and Can create role. Write down the username and password in a secure place.
  2. Next, create a new database (e.g. my_database) also in the Users & DBs tab. Make sure to assign the user you just created as its owner.

D. Create Your PostgreSQL Url

  1. Now we need to create a connection URL to your PostgreSQL database using the following format:
    postgresql://__username__:__password__@__postgres__:5432/__database__?ssl=true.
  2. The __username__ , __password__ , and __database__ portions you created in the Database Setup above.
  3. To get the __postgres__ portion, go back to the Overview tab. There, you’ll see a connection string that starts with jbdc:postgresql:// and continues with :5432/<your-database-name> . The part between those two parts is your __postgres__ string.
  4. Write down the complete PostgreSQL connection url in a secure place.

E. Create an Account With or Sign into Vercel

  1. If you don’t already have an account with Vercel, sign up here (and create a team / org if necessary): https://vercel.com/signup
  2. If you haven’t already installed Vercel’s command-line interface (CLI):
    yarn global add now or npm i -g now .
  3. Log into now via the CLI: now login

F. Add Secrets

1. Add Secret DATABASE_URL to Prisma

You’ll notice that the prisma/schema.prisma file uses an environment variable for the PostgreSQL database connection string env("DATABASE_URL"). Make it available to Prisma by entering into your CLI:

export DATABASE_URL="postgresql://..." (the link you created in step D.)

2. Add Secrets to Your Local Development

Next, create a .env file and a .env.build file at the root of your app. Add your environment variables there. This lets your app use these variables for local development.

APP_AUTH="somerandompassword"
DATABASE_URL="postgresql://..."

Notice that both .env files have been added to the .gitignore file, since we don’t want to expose your secrets when you push your code elsewhere.

3. Add Secrets to Your Now Project

To make environment variables available to for deployment requires a two-fold process:

  1. Creating now-specific environment variables (e.g. database_url) and adding them via the CLI.
  2. Making them accessible via the now.json file to your server, which will create new environment variables during runtime (e.g. DATABASE_URL).

The second step has already been done for you in the demo repository; see the now.json file located in the root of that repo. However, be sure to use the same variable names you specified in your .env file. It’s good practice to capitalize the environment variables used by your app (e.g. DATABASE_URL and lowercase the corresponding secret passed into Now (e.g. database_url).

Here’s how you add your secrets in step 1, using the CLI.

now secrets add app_auth "somerandompassword"

now secrets add database_url "postgresql://..."

G. Test Your GraphQL Server

  1. Fire up your first local development GraphQL server! now dev (also located as a script under yarn start. If you navigate to http://localhost:3000/api, you should see a GraphQL Playground. If you type in: { hello } you’ll get your first “Hello, world!” example!

H. Create Database Tables Using Prisma Migrate

Keep in mind that as of this writing Prisma Migrate is still an experimental feature. Using your command line, type yarn prisma:commit to run the Prisma Migrate script in the package.json file.

If everything looks good, run yarn prisma:push to push your schema to the database.

Congratulation! You now have a working database with a schema. 🎉

I. Seed Your Database With Sample Data

  1. Let’s seed our database with some sample data, provided in /prisma/seed. Run yarn prisma:seed Once complete, exit the process (control+c).
  2. Let’s see if that worked! Run Prisma’s shiny new Studio at http://localhost:5555: yarn prisma:studio
  3. Another way to test your data is to start up the GraphQL server: now dev and query all users at http://localhost:3000/api:

J. Deploy Your App

In your console, type:

now --prod

and accept the defaults. Ready go! Open a browser and navigate to the URL that Vercel’s Now has copied into your clipboard. You should now see data that’s been queried from your server inside a purple box, like this:

Hopefully it should work now! 🤞

Add /api at the end of that URL to access your GraphQL Playground.

Prisma Postscript

Here’s a little power user secret to fully unlock the power of Prisma Client in VisualStudio Code.

  1. Download the Prisma extension: https://marketplace.visualstudio.com/items?itemName=Prisma.prisma
  2. In your server code, the Prisma Client is initialized in /api/index.js and then passed into the resolvers via the context. If you remove the { prisma } import in a resolver and instead import Prisma Client locally, you’ll enable Prisma auto-suggestions.

Change a resolver from this:

to this:

However, in production, it’s better to instantiate your Prisma Client only once, at the root: /api/index.js and then pass it into your resolvers.

That’s it! This essay is a contribution from Ecstatic Engineering at ecstatic.com. If you’re a curious engineer, live in (or want to move to) Vancouver, British Columbia, and would like to do great work in an amazing environment with wonderful people, reach out!

© 2020 Ecstatic Life Inc under an Attribution-NonCommercial 4.0 International Creative Commons licence.

--

--