Deploying a Prisma GraphQL API

Joshua Hall

In this article, we’re going to go over how to deploy your Prisma API for production use for your sites and apps. For the purposes of this article, we’ll be making use of Prisma Cloud and Heroku to deploy our service.

Prerequisites

You’ll need a basic Node.js-based Prisma GraphQL application, which you can clone from this boilerplate repo here. Just remember to move into the prisma folder and start a new Docker container.

$ npm install
$ docker-compose up -d
$ prisma deploy

You’ll also need to know how to setup and connect to your Postgres database in Heroku, which you can brush up on here.

Installation

The only new thing you’ll need is env-cmd, since we’re going to be reconfiguring some variables to be different in development vs production mode.

$ npm install env-cmd

Creating a Prisma Service

For hosting our Prisma container, as we had on port 4466, we’re going to be using Prisma Cloud. Once you’ve logged in using your Github account, on the Servers page you’ll be able to start with ADD SERVER.

Prisma servers screenshot

Once you’ve named your server it’ll walk you through a few steps. Create a new database, connect it to your Heroku account, and set it as a PostgreSQL-type database. Creating the Server will be a similar process.

Now if you look at your Heroku account you should see your new database already added. Like before, we’ll grab our Postgres credentials and add them to our projects docker-compose.yml file.

Prisma Configuration

Currently, our configuration is looking at localhost:4466 (or your docker ip), which isn’t where our new server is. We don’t want to hard code either as our endpoint since we’ll want to transition between them.

We’re going to do this by creating two .env files, each with a different endpoint and we’ll tell Prisma which to use when we want to do anything.

prisma.yml

endpoint: ${env:ENDPOINT}
datamodel: datamodel.graphql

dev.env

ENDPOINT=http://192.168.99.101:4466/ #Or http://localhost:4466 on Mac

Now when you run prisma deploy if you use the -e flag you can specify where which env file you wish to use is. So prisma deploy -e ./dev.env should work just like before.

We can get our server endpoint by using our empty prod.env file, which should open a helpful little interface to create our service and connect it to your server, which for me is alligator-example.

Screenshot: deploy to an existing server

Once you name your service and set the stage to prod you should be able to see your new service over at Prisma Cloud.

Screenshot: our service on Prisma Cloud

Even cooler, now if you look back at prisma.yml you’ll see a new services endpoint added to the file, which we can take and move over to the production env file.

prod.env

ENDPOINT=https://alligator-example-342bdfs2.herokuapp.com/alligator-prisma-example/prod

Now we can use our environment variable trick to easily move between testing the dev and production databases.

Node.js Configuration

Prisma is only one half of our application, we still need a way for Node to access either the production or development servers and databases. Our first step is to change any references to our local container into an environment variable, just like we did in the Prisma config.

prisma.js

const prisma = new Prisma({
  typeDefs: 'prisma/generated.graphql',
  endpoint: process.env.ENDPOINT
})

Now, we need to reconfigure our scripts for Heroku and have them look for our env files before doing anything.

Let’s move everything from the start script into a new dev script and use env-cmd to point it to the dev.env file. We’ll use start as our production script since that’s what Heroku uses by default. The only difference from dev is that it uses the prod.env file, uses Node instead of nodemon, and looks for the bundled version of our app.

One problem, Heroku doesn’t know how to handle our unprocessed code without Babel, so we need to add a postbuild process to build out our app into something more usable and direct our start script to that. heroku-postbuild just bundled everything in src into a separate dist folder.

package.json

{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "get-schema": "graphql get-schema -p prisma",
    "start": "env-cmd ./prisma/prod.env node dist/index.js",
    "heroku-postbuild": "babel src --out-dir dist --copy-files",
    "dev": "env-cmd ./prisma/dev.env nodemon src/index.js --ext js,graphql --exec babel-node"
  },
}

For me, env version 9.0+ gave me consistent problems, although 8.0.2 works fine. You might want to try downgrading if you encounter any persistent issues.

Finally, we need to make a slight tweak to which port our graphql-yoga server is starting on. We want it to use either the port given by Heroku or a default for local development.

index.js

const port = process.env.PORT || 3000
server.start(port, () => console.log('server running'))

Now when you connect this repo to Heroku it should automatically deploy your API as a GraphQL playground that anyone can access.

Closing Thoughts

Prisma has easily become my favorite way of working with databases, but since it’s so new there still isn’t much support in other cloud hosting services like AWS or Google Cloud. Still, it’s better to get comfortable with it now since Prisma will only become more common and powerful as other services start supporting it.

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#