Tutorial

Prisma with Node.js: Prisma Bindings

GraphQL
This tutorial is out of date and no longer maintained.

Warning: This tutorial is out of date and no longer maintained. It is based on Prisma 1 which is not actively developed any more. To learn everything about the latest version of Prisma, visit the official Prisma documentation.

If you want to learn how to build server-side applications with Prisma, you can follow these new tutorials:

Introduction

In this tutorial, you will explore using the prisma-bindings library to start using all the superpowers that Prisma has generated for us.

Prerequisites

You’re going to need to have a basic Prisma container setup and connected to a database. In this case, we’ll be using the Postgres setup.

If you want to jump into the implementation, you can copy this boilerplate to get started, just remember to change the endpoints to your Docker container.

You should also be comfortable with using mutations and subscriptions and creating schemas and resolvers.

Queries

Since we passed our prisma object over to our server’s context in index.js we can access it in our resolver context, which we’ll just destructure out.

Everything available to you in our Prisma container’s documentation is now available on our prisma object. If we want to make a request for users we can access it on prisma.query. Every request you make will require two arguments, the query arguments, like data or where, and the properties that your user wants. If you only need one, you can just pass null in its place.

Everything we pass as the second argument, which needs to be an object in a string, will control what the user is allowed to query for. In this case name will be available, but a request for their id will fail:

resolvers.js
const Query = {
  users(parent, args, { prisma }, info) {
    const users = prisma.query.users(null, '{ name }');
    return users;
  },
};

To make everything available to the user, we can pass-in info since that contains the user’s full query.

Passing in where or data is similar, but it doesn’t need to be in a string.

const Query = {
  users(parent, args, { prisma }, info) {
    const users = prisma.query.users({ where: { id: args.id } }, info)
    return users
  },
  user(parent, args, { prisma }, info) {
    return prisma.query.user({ where: { id: args.id } }, info)
  }
};

Since we’re working with filters on our queries, we need to update our schema to allow for an id to be passed-in.

schema.js
type Query {
  users(id: ID): [User!]!
  user(id: ID!): User!
}

type User {
  id: ID! 
  name: String!
}

Mutations

First, you’re going to need to add our exported mutations to our server’s resolvers in index.js.

index.js
import { Query, Mutation } from './resolvers'

const server = new GraphQLServer({
  typeDefs: './schema.graphql',
  resolvers: {
    Query,
    Mutation
  },
  context: { prisma }
})

Mutations are just as easy as queries, just access the method you want on prisma and pass the arguments and what you want to be returned to the user. This time, let’s try chaining mutations together to create a user then update their name. For this, we can use async/await and pass the id from the new user to the update method.

resolvers.js
const Mutation = {
  async addUser(parent, args, { prisma }, info) {
    const newUser = await prisma.mutation.createUser({ data: args.data }, info)

    const updatedUser = await prisma.mutation.updateUser({
      where: { id: newUser.id },
      data: { name: "Overridden" }
    }, info)

    return updatedUser
  }
}
schema.graphql
type Mutation {
  addUser(data: CreateUserInput): User!
}

input CreateUserInput {
  name: String!
}

Subscriptions

For GraphQL subscriptions using Prisma, we don’t even need to worry about pubsub or opening sockets; we can just use prisma to use a subscription in one line.

First, let’s add our Subscriptions to our resolvers and setup our schema to support them. We’ll also be adding a smaller updateUser method that we’ll use to test it with.

index.js
import { Query, Mutation, Subscription } from './resolvers'

const server = new GraphQLServer({
  typeDefs: './schema.graphql',
  resolvers: {
    Query,
    Mutation,
    Subscription
  },
  context: { prisma }
})
schema.graphql
type Mutation {
  addUser(data: CreateUserInput): User!
  updateUser(id: ID!, data: CreateUserInput): User!
}

enum MutationType {
  CREATED
  UPDATED 
  DELETED
}

type Subscription {
  user(id: ID!): UserSubscriptionPayload!
}

type UserSubscriptionPayload {
  mutation: MutationType!
  node: User
}

Just like before, we can access a user subscription on prisma.subscription.user, and set it to watch the user whose id we’re going to pass to it.

resolvers.js
const Subscription = {
  user: {
    subscribe(parent, args, { prisma }, info) {
      return prisma.subscription.user({ where: { node: { id: args.id } } }, info)
    }
  }
}

const Mutation = {
  async addUser(){...},
  updateUser(parent, args, { prisma }, info) {
    return prisma.mutation.updateUser({
      where: { id: args.id },
      data: args.data
    }, info)
  }
}

Conclusion

Prisma made what was before a lot of menial tasks that had to be done every time we wanted to add a new type, and simplified them into many one-line functions that are incredibly easy to use. While it still gives us the freedom to do what we need in between getting a request and working with the database.

Warning: This tutorial is out of date and no longer maintained. It is based on Prisma 1 which is not actively developed any more. To learn everything about the latest version of Prisma, visit the official Prisma documentation.

If you want to learn how to build server-side applications with Prisma, you can follow these new tutorials:

Creative Commons License