prisma2-example

A GraphQL backend using nexus/schema, apollo-server, and prisma 2

Stars
0

GraphQL Backend Example

An example GraphQL Backend using Prisma2, Apollo Server, nexus/schema, and using SQLite.

✅ Features

📝 Workflows

1. Initial DB Setup

This will be the first workflow one has to go through to initially setup the repo for further development.

After cloning the repo:

Decide what data source you want to use. If you want to use SQLite leave the prisma/schema.prisma file as is. However if you wish to change the data source refer to https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-schema/data-sources

An example data source for postgresql would be:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

Make sure to create a .env file located at prisma/.env that includes DATABASE_URL=some_database_url.

For SQLite this URL will be a file path, for example DATABASE_URL=file:./dev.db.

Once you've set up your data source:

  • npm i to install deps
  • npm run migration:run to create database
  • create a .env in the root of the project and add an APP_SECRET=app_secret_goes_here to it
  • npm run prisma:seed to seed initial data
  • Ensure that the postinstall script ran, if it didn't run npm run generate

2. DB Migration

This is the workflow one would go though to change the data model from it's current state.

After changing the prisma/schema.prisma file:

  • npm run migration:save to create the migration file
  • npm run migration:run to run the migration and alter the DB
  • npm run generate to generate the new prisma client

3. View DB data

This workflow enables you to locally view and edit the database with a GUI.

After at least workflow 1 is completed successfully and running all migrations:

  • npm run prisma:studio to open prisma studio and view/edit data

4. Run Server

This is the workflow one uses to start the GraphQL server and connect it to the database.

To start the server for local development after at least workflow 1 is completed successfully:

  • npm run start:dev to start the server in watch mode
  • visit the URL logged to the console to use the playground

To start the dist server after at least workflow 1 is completed successfully:

  • npm run build to compile the typescript and put it in dist
  • npm run start to start the server
  • visit the URL logged to the console to use the playground

5. Change the GraphQL Schema

This workflow details how to re-generate the TypeScript definitions and GraphQL schema SDL after changing the schema from it's current state.

After at least worflows 1 and 4 are completed successfully:

  • Edit src/schema.ts
  • npm run generate to generate new GraphQL types and schema

6. Build the App

After at least workflows 1 and 4 are completed successfully:

  • npm run build to generate the dist code
  • npm run start to start the dist code

7. Authentication

All GraphQL Queries and Mutations except for login and singup are protected by authentication.

To login after at least workflows 1 and 4 are completed successfully:

  • login with the seeded user by sending a login mutation with email and password
  • add that token to the headers of following requests with the format Authorization: Bearer <token_here>, if you're using the GraphQL playground it expects an object with the format { 'Authorization': 'Bearer <token_here>' }

To signup after at least workflows 1 and 4 are completed successfully:

  • sign up with a new user by sending a signup mutation with at least email and password
  • add that token to the headers of following requests with the format Authorization: Bearer <token_here>, if you're using the GraphQL playground it expects an object with the format { 'Authorization': 'Bearer <token_here>' }

🏗 Structure

Prisma/DB

  • prisma/schema.prisma - acts as the DB schema that also includes the connection details. Editing this and then creating and running migrations is the primary way to change the DB.
  • prisma/migrations - contains the code and documentation for all of the migrations the DB needs to be up to date.
  • prisma/seed.ts - contains the code to seed the DB with test data.

Server/GraphQL

  • src/schema.ts - contains the code describing the GraphQL schema, it contains Entity definitions, Query and Mutation definitions, along with the resolvers for all fields. It uses nexus/schema and nexus-plugin-prisma to integrate the types and resolvers that prisma provides.
  • src/context.ts - sets up the apollo context object so you can use prisma queries and mutations inside of resolvers.
  • src/server.ts - sets up the apollo server and runs it
  • src/generated/nexus.ts - contains the auto-generated TypeScript types from nexus/schema
  • schema.graphql - contains the auto-generated GraphQL SDL from nexus/schema

Auth/Permissions

  • src/permissions/index.ts - contains the definition of the rules that control permissions, and applies those rules to fields on the GraphQL schema
  • src/utils/auth/password.ts - utilities to hash and compare passwords
  • src/utils/auth/token.ts - utilities to sign and verify JWT tokens
  • src/utils/auth/getUserId.ts - utility to take an incoming auth header and return the verified userId from the JWT

🚀 Deployment

Heroku

Heroku deployment using Postgres as the database.

  • Create a Heroku app
  • Add a Procfile to the root of the project:
release: npm run migration:run:up
web: npm run start

Will run migrations after the app builds and then start the web server.

  • Set up Heroku to pull from the desired repo
  • Add the node buildpack to the app
  • Add the Heroku Postgres add-on to the app
  • Add all of the necessary environment variables to the Config Vars section in the app settings
    • APP_SECRET (required)
    • DATABASE_URL (required)
    • GRAPHQL_INTROSPECTION (optional)
    • GRAPHQL_PLAYGROUND (optional)
  • Add NODE_MODULES_CACHE:false to the Config Vars, this is because the prisma client should not be cached
  • Run a manual deploy of the app
  • Turn on the web process in the resources tab of the app

🕵️‍♀️ Troubleshooting

  • If you are using SQLite as the data source for the API you can delete all data and start fresh by deleting the file that SQLite is connected to, for example ./prisma/dev.db, and re-running npm run migration:run and npm run prisma:seed.
  • If you run into issues with Prisma (i.e. prisma-client, studio, or migrations) try:
    • Delete node_modules using rm -rf node_modules when at the root of the project
    • Re-install dependencies npm i
    • Ensure the Prisma client has re-generated

🌐 Links

Prisma

GraphQL

Auth

Heroku