Getting Started with Yoga and Prisma for Building GraphQL Servers

By now, you have probably heard a lot of buzz about GraphQL going around and how it’s going to replace REST but you don’t even know where to begin. You hear a lot of buzzwords about mutations and queries but what you’re used to is GET and POST requests on your different endpoints to fetch data and make changes to your database. Thinking about making a switch to GraphQL and don't know where to begin? This article is for you.

In this article, we are going to take a look at how to convert a database to a GraphQL API using Prisma.

Prerequisites

To follow through this article, you’ll need the following:

Table of Contents

    • Basic knowledge of JavaScript
    • Node installed on your machine
    • Node Package Manager installed on your machine

    To confirm your installations, run the command:

    node --version
    npm --version

    If you get their version numbers as results then you’re good to go!

    Using Prisma to connect GraphQL to a database

    Prisma is a service that allows you to build a GraphQL server with any database with ease. To get started with using Prisma, you need to install the command line interface first:

    npm install -g prisma

    This globally installs prisma for future use on your machine. The next thing you need to do is to create a new service. To do this, run the command:

    prisma init scotch-prisma-demo

    When you run this command, a prompt will be shown for you to decide what server you want to connect to.

    For demo purposes, select the Demo Server option and then a browser prompt will be shown to register with Prisma Cloud. After successful login, click the CREATE A NEW SERVICE option and then copy the key required to log in to Prisma from the page.

    Head over to your terminal, close the current process if it’s still running and then login to prisma by pasting the command copied from the browser into the terminal:

    Login to Prisma

    Once you’ve successfully signed in, return to the command line and select the region for your demo server and follow the remaining prompts as shown below:

    Creating new Prisma Service

    You can also head over here if you want to connect Prisma with own database.

    Now that the service has been created, you need to deploy it. To do this, head over to the scotch-prisma-demo directory and run the deploy command:

    cd scotch-prisma-demo
    prisma deploy

    Deploying Prisma Service

    Once deployment is complete, on the Prisma Cloud you can see a list of your deployed services:

    List of Services on Prisma Cloud

    To open the GraphQL API and start sending queries and running mutations, run the command:

    prisma playground

    Running Sample Queries using Prisma Service

    Updating Schema

    When the scotch-prisma-demo folder was created, two files were created in the folder

    • prisma.yml - containing the endpoint and datamodel for the server.
    • datamodel.graphql - Containing the schema for the server.

    Edit the datamodel.graphql file to look like this:

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

    This means the schema will contain the ID and name for the user. To update the schema, run the command:

    prisma deploy

    Using Yoga and Prisma Binding to interact with Prisma Service

    In the last section, we saw how to use Prisma to turn a database into GraphQL API and then run Queries and mutations from the playground. Here’s the thing though. In a real-life application, leaving all this functionality to anyone who has access to the Prisma means that the client has the entire database exposed to them and this is not good.

    To to this, Prisma has the graphql-yoga and prisma-binding which allow you to build a GraphQL server on top of the Prisma service by connecting the resolvers of the GraphQL server to Prisma’s GraphQL API using Prisma binding.

    In the scotch-prisma-demo folder initialize a node project using the command:

    npm init -y

    This automatically creates a package.json file for your project

    Installing the necessary modules

    To continue building the graphql server, we will need to install the following modules by running the command:

    npm install graphql-yoga prisma-binding

    Reorganize File Structure

    Run the following commands:

    mkdir prisma
    mv datamodel.graphql prisma/
    mv prisma.yml prisma/
    mkdir src
    touch src/index.js
    touch src/schema.graphql

    Creating Application Schema

    The GraphQL server needs to have a Schema that helps identify the operations that can be carried out on the server. For this application, edit the src/schema.graphql to look like this:

    type Query{
        user(id: ID!): User
    }
    
    type Mutation {
        signup(name: String!): User!
    }

    In this case, the schema allows for the following:

    • Fetch a single user based on its id
    • Signup a user to the system

    Downloading Prisma Database Schema

    If you look at the schema definition above, you can see that the User is not defined. Ideally, you could redefine the User type in the schema but since there already exists a definition in the Prisma service created earlier, we will use that instead to prevent us from having multiple locations for one definition.

    Install the GraphQL CLI by running:

    npm install -g graphql-cli

    and then create a .graphqlconfig in the root directory of the project and update it as follows:

    touch .graphqlconfig.yml
    projects:
        app:
            schemPath: src/schema.graphql
            extensions:
                endpoints:
                default: http://localhost:4000
        prisma:
            schemaPath: src/generated/prisma.graphql
            extensions:
                prisma: prisma/prisma.yml

    You can download the Prisma schema by running the following command:

    graphql get-schema --project prisma

    Then, update the src/schema.graphql to look like this:

    import User from './generated/prisma.graphql'
    
    type Query{
        user(id: ID!): User
    }
    
    type Mutation {
        signup(name: String!): User!
    }

    You have the Prisma schema downloaded in the /src/generated/prisma.graphql file.

    Instantiating Prisma bindings and Implementing Resolvers

    The next thing to do is to ensure that Prisma’s GraphQL API can be accessed by the resolvers using the prisma-binding. To do this, update the index.js file to look like this:

    // src/index.js
    const { GraphQLServer } = require('graphql-yoga')
    const { Prisma } = require('prisma-binding')
    
    const resolvers = {
        Query: {
            user: (_, args, context, info) => {
                // ...
            }
        },
        Mutation: {
            signup: (_, args, context, info) => {
                // ...
            }
        }
    }
    
    const server = new GraphQLServer({
        typeDefs: 'src/schema.graphql',
        resolvers,
        context: req => ({
            req,
            prisma: new Prisma({
                typeDefs: 'src/generated/prisma.graphql',
                endpoint: 'PRISMA_ENDPOINT',
            }),
        }),
    })
    server.start(() => console.log(`GraphQL server is running on http://localhost:4000`))

    Note that the PRISMA_ENDPOINT can be obtained from your /prisma/prisma.yml file.

    Update the resolvers in your application by adding the following into your index.js file:

    // src/index.js
    [...]
    
    const resolvers = {
        Query: {
            user: (_, args, context, info) => {
                return context.prisma.query.user(
                    {
                        where: {
                            id: args.id,
                        },
                    },
                    info
                )
            }
        },
        Mutation: {
            signup: (_, args, context, info) => {
                return context.prisma.mutation.createUser(
                    {
                        data: {
                            name: args.name,
                        },
                    },
                    info
                )
            }
        }
    }
    
    [...]

    Update your package.json file as follows:

    {
        "name": "scotch-prisma-demo",
        "version": "1.0.0",
        "description": "",
        "main": "index.js",
        "scripts": {
        "start": "node src/index.js",
        "test": "echo \"Error: no test specified\" && exit 1"
        },
        "keywords": [],
        "author": "",
        "license": "ISC",
        "dependencies": {
        "graphql-yoga": "^1.14.7",
        "prisma-binding": "^2.0.2"
        }
    }

    Here, we added the start script to the project. Now, you can run the application by using this command:

    npm start

    This starts the server and the playground for use. When you head over to the browser and navigate to localhost:4000, you get the following:

    Running a Mutation in the Playground

    Running a Query in the Playground

    Now that we have built the GraphQL server over the Prisma Service, the playground no longer connects directly to the Prisma Endpoint but to the application itself. With this, the client is restricted to only performing actions that have been defined in the new schema on the server.

    Conclusion

    In the article, we have seen how to create a Prisma service that converts a database to a GraphQL API and how to use GraphQL Yoga and Prisma Binding to build a GraphQL server on the service for use by client applications. Here’s a link to the GitHub repository if interested. Feel free to leave a comment below.

    Chris Nwamba

    104 posts

    JavaScript Preacher. Building the web with the JS community.