Access Prisma from a Node Script using Prisma Bindings
1 votes
82 views
by Nikolas Burk

Introduction

In this tutorial, you will learn how to access an existing Prisma API from a simple Node script using Prisma bindings.

The tutorial assumes that you already have a running Prisma API, so please make sure to have the endpoint for it available. If you're unsure about how to get the endpoint for a Prisma API, visit the Get Started section in the Prisma docs.

Update the data model

You already have your existing Prisma service, but for this tutorial we need to make sure that it has the right data model for the upcoming steps.

Note that we're assuming that your data model lives in a single file called datamodel.graphql. If that's not the case, please adjust your setup.

Step 1

Open datamodel.graphql and update its contents to look as follows:

type User {
  id: ID! @unique
  name: String!
  posts: [Post!]!
}

type Post {
  id: ID! @unique
  title: String!
  content: String!
  published: Boolean! @default(value: "false")
  author: User!
}
Step 2

After you saved the file, open your terminal and navigate into the root directory of your Prisma service (the one where prisma.yml is located) and run the following command to update its GraphQL API:

prisma deploy

The GraphQL API of your Prisma service now exposes CRUD operations for the User as well as the Post type that are defined in your data model and also lets you modify relations between them.

Setup project directory

Now that you have updated your data model, you will setup your directory structure.

Step 3

Navigate into a new directory and paste the following commands in your terminal:

mkdir -p my-node-script/src
touch my-node-script/src/index.js
cd my-node-script
yarn init -y
Step 4

Next, move the root directory of your Prisma service into my-node-script and rename it to prisma.

cd ..
mkdir my-node-script/prisma
mv datamodel.graphql prisma.yml my-node-script/prisma
cd my-node-script
.
└── my-node-script
    ├── package.json
    ├── prisma
    │   ├── datamodel.graphql
    │   └── prisma.yml
    └── src
        └── index.js
Step 5

Next, install prisma-binding:

yarn add prisma-binding graphql

Download the Prisma database schema

The next step is to download the GraphQL schema of Prisma's GraphQL API (also referred to as Prisma database schema) into your project so you can point Prisma binding to them.

Downloading the Prisma database schema is done using the GraphQL CLI and GraphQL Config.

Step 6

Install the GraphQL CLI using the following command:

yarn global add graphql-cli
Step 7

Next, create your .graphqlconfig in the root directory of the server (i.e. in the my-node-script directory):

touch .graphqlconfig.yml
Step 8

Put the following contents into it, defining Prisma's GraphQL API as a project:

projects:
  prisma:
    schemaPath: src/generated/prisma.graphql
    extensions:
      prisma: prisma/prisma.yml

The Steprmation you provide in this file is used by the GraphQL CLI as well as the GraphQL Playground.

Step 9

To download the Prisma database schema to src/generated/prisma.graphql, run the following command in your terminal:

graphql get-schema

The Prisma database schema which defines the full CRUD API for your database is now available in the location you specified in the projects.prisma.schemaPath property in your .graphqlconfig.yml (which is src/generated/prisma.graphql).

If you want the Prisma database schema to update automatically every time you deploy changes to your Prisma services (e.g. an update to the data model), you can add the following post-deployment hook to your prisma.yml file:

hooks:
  post-deploy:
    - graphql get-schema -p prisma

Send queries and mutations

In this step, you will communicate with your Prisma service using Prisma binding.

Therefore, you first instantiate a Prisma binding by pointing it to the schema you downloaded in the previous step. The binding instance needs to connect to your Prisma API, so you also need to provide the endpoint of your Prisma API (which you can find stored in prisma/prisma.yml).

The Prisma binding instance acts as a "JavaScript SDK" for your Prisma service. You can use its API to send queries and mutations to your Prisma database.

Step 10

Put the following code in src/index.js. It creates a Prisma binding instance and uses it to send queries and mutations to your Prisma service.

⚠️ Important: Remember to replace the value of __YOUR_PRISMA_ENDPOINT__ with your Prisma endpoint, which is stored in prisma/prisma.yml.

const { Prisma } = require("prisma-binding")

const prisma = new Prisma({
  typeDefs: "src/generated/prisma.graphql",
  endpoint: "__YOUR_PRISMA_ENDPOINT__"
})

prisma.mutation
  .createUser({ data: { name: "Alice" } }, "{ id name }")
  .then(console.log)
  // { id: 'cjhcidn31c88i0b62zp4tdemt', name: 'Alice' }
  .then(() => prisma.query.users(null, "{ id name }"))
  .then(response => {
    console.log(response)
    // [ { id: 'cjhcidn31c88i0b62zp4tdemt', name: 'Alice' } ]
    return prisma.mutation.createPost({
      data: {
        title: "Prisma rocks!",
        content: "Prisma rocks!",
        author: {
          connect: {
            id: response[0].id
          }
        }
      }
    })
  })
  .then(response => {
    console.log(response)
    /*
      { id: 'cjhcidoo5c8af0b62kv4dtv3c',
        title: 'Prisma rocks!',
        content: 'Prisma rocks!',
        published: false }
    */
    return prisma.mutation.updatePost({
      where: { id: response.id },
      data: { published: true }
    })
  })
  .then(console.log)
  /*
    { id: 'cjhcidoo5c8af0b62kv4dtv3c',
      title: 'Prisma rocks!',
      content: 'Prisma rocks!',
      published: true }
  */
  .then(() => prisma.query.users(null, "{ id posts { title } }"))
  .then(console.log)
  // [ { id: 'cjhcidn31c88i0b62zp4tdemt', posts: [ [Object] ] } ]
  .then(() => prisma.mutation.deleteManyPosts())
  .then(console.log)
  // { count: 1 }
  .then(() => prisma.mutation.deleteManyUsers())
  .then(console.log)
// { count: 1 }
Step 11

Run the script to see the query results printed in your terminal.

node src/index.js

Check for existence of specific nodes

Besides query and mutation, Prisma binding provides a handy property called exists which allows you to check whether a node with certain properties exists in the database that is managed by Prisma. The exists property exposes one function per type in your data model - each function is named after the type it represents (in your case that's prisma.exists.User(filter) and prisma.exists.Post(filter)). These functions receive filter arguments and always return true or false.

Because the datamodel has two models, User and Post, Prisma generated exists.User and exists.Post.

Step 12

Put the following code in src/index.js. It instantiates a Prisma binding instance and uses it to send queries and mutations to your Prisma service.

⚠️ Important: Remember to replace the value of __YOUR_PRISMA_ENDPOINT__ with your Prisma endpoint, which is stored in prisma/prisma.yml.

const { Prisma } = require("prisma-binding")

const prisma = new Prisma({
  typeDefs: "src/generated/prisma.graphql",
  endpoint: "__YOUR_PRISMA_ENDPOINT__"
})

prisma.mutation
  .createUser({ data: { name: "Alice" } }, "{ id name }")
  .then(response => {
    return prisma.mutation.createPost({
      data: {
        title: "Prisma rocks!",
        content: "Prisma rocks!",
        author: {
          connect: {
            id: response.id
          }
        }
      }
    })
  })
  .then(() => prisma.exists.User({ name: "Alice" }))
  .then(response => console.log(response))
  // true
  .then(() => prisma.exists.Post({ title: "Prisma rocks" }))
  .then(response => console.log(response))
  // true
  .then(() => prisma.mutation.deleteManyPosts())
  .then(() => prisma.mutation.deleteManyUsers())
  .then(() => prisma.exists.Post({ title: "Prisma rocks" }))
  .then(response => console.log(response))
  // false
  .then(() => prisma.exists.User({ name: "Alice" }))
  .then(console.log)
  // false
Step 13

Run the script to see the query results printed in your terminal:

node src/index.js

Send raw queries and mutations

Prisma binding also lets you send queries and mutations as strings to your Prisma service using the request property. This is more verbose because you need to give spell out the entire query/mutation, and also their responses have a little more overhead because they include the name of the query/mutation as a top level key.

Prisma binding's request uses graphql-request under the hood and therefore has the same API.

Step 14

Replace the contents of src/index.js with the following code.

⚠️ Important: Remember to replace the value of __YOUR_PRISMA_ENDPOINT__ with your Prisma endpoint, which is stored in prisma/prisma.yml.

const { Prisma } = require("prisma-binding")

const prisma = new Prisma({
  typeDefs: "src/generated/prisma.graphql",
  endpoint: "__YOUR_PRISMA_ENDPOINT__"
})

const query = `
  {
    users {
      id
      name
    }
  }
`
const mutation = `
  mutation CreateUser($name: String!) {
    createUser(data: { name: $name }) {
      id
      name
    }
  }
`

const variables = { name: 'Bob' }

prisma.mutation
  .createUser({ data: { name: 'Alice' } }, '{ id name }')
  .then(console.log)
  // { id: 'cjhcijh30cgww0b622rwkkvbo', name: 'Alice' }
  .then(() => prisma.request(mutation, variables))
  .then(console.log)
  // { createUser: { id: 'cjhcijjndch0d0b62qux6o52a', name: 'Bob' } }
  .then(() => prisma.query.users(null, '{ id name }'))
  .then(console.log)
  /*
    [ { id: 'cjhciiacxcf850b62mcuaa3uz', name: 'Alice' },
      { id: 'cjhcijjndch0d0b62qux6o52a', name: 'Bob' } ]
  */
  .then(() => prisma.request(query))
  .then(console.log)
  /*
    { users:
      [ { id: 'cjhciiacxcf850b62mcuaa3uz', name: 'Alice' },
        { id: 'cjhcijjndch0d0b62qux6o52a', name: 'Bob' } ] }
  */
Step 15

Run the script to see the query results printed in your terminal.

node src/index.js