My journey with Prisma at Tech47

Written by Toumi Maximilien

6 min read ·

Let me explain Prisma to you

Grandma - What is this i don't even

From the Prisma website it is define as follow:

A performant open-source graphql ORM-like layer doing the heavy lifting in your Graphql server.

what-does-that-even-mean-spiderman-jjJvhK

Well Prisma is an API service that sits between the graphql server and the database (NoSQL/SQL) name it, it is an abstraction layer of the database but!! It is not a database. While Prisma effectively represents the database layer in your backend stack, it is not actually a database! It is an abstraction layer on top of a database that lets you interact with the database using GraphQL instead of SQL or another database’s specified query language. This means you’re keeping full ownership of your data. You’re still getting the performance you’d expect while being leveraging GraphQL as a simple interface. Prisma is designed in a way that it auto-generate a comprehensive and powerful CRUD operation and subscription based on our data model, on top of it, it provides a tool which you can use to play around with your data. Isn’t it cool? At this point, with Prisma you just need to define your data model and start playing around with it. By playing around with your data I mean writing queries and mutations etc. and actually see the output. Okay, let see how it works.

Graphql server architecture with Prisma

prisma

When building graphql server with Prisma we are actually dealing with two graphql APIs

  • The database layer power by Prisma service which provides CRUD operations and real-time interaction with the database
  • The Application layer : is the part of the application that is exposed to the client (frond end application), it is responsible for any functionality that is not directly related to writing or reading data from the database like: • Business logic • Authentication and permission • 3rd party integrations two questions may come to your mind at this point. How does the application layer interact with our database? And why don’t we use Prisma Graphql API directly from our client application?

How does the application layer interact with our database?

Thanks to Prisma bindings.

Thanks-a-Million-Banner

As a backend developer after defining the schema of our application we need to define resolvers to query directly our database using database’s specified query language. Let me remind you that we already have all we need to interact with our database. There is no need to worry about how to write our queries with database’s specified query language because Prisma API service does it for us. Thanks for another feature of Prisma called Prisma bindings. Prisma-binding provides a convenience layer for building GraphQL servers on top of Prisma services. In short, it simplifies implementing your GraphQL resolvers by delegating execution of queries (or mutations) to the API of the underlying Prisma database service. Rather than writing SQL or accessing a NoSQL database API like MongoDB inside our resolvers.

Why don’t we use the Prisma API directly from our client application?

Prisma as I mentioned earlier generates and exposes powerful CRUD operation to interact with our database on our data model therefore using Prisma API directly from our client application will expose our entire database schema to the client. Let say you have a user type and one of the field is the password you definitely don’t want the password to be accessed by the client application directly. Click here

for more information. Enough of theory lets dive into some examples.

coding

In this session we are going to cover the concepts we just covered: We are going to write a little application and see how stuff work with Prisma. I will be showing the different applications layer of Prisma’s graphql server and how Prisma bindings are implemented on the client application layer. First of all let us set up Prisma’s graphql server locally using Docker. I will not explain each and everything here in details just I want to illustrate what we have covered so far.

Step1: Setup our Prisma API Service with Prisma Cloud(online)

Sans titre

Sans titre

At this point, we are using the Prisma Cloud service to initialize our Prisma graphql service by running the command Prisma init blog01 Where blog01 is the root folder of our application. Two files are created:

  • Prisma.yml: the configuration file
  • Datamodel.graphql : the based data model To know more go here

Let follow the next steps mentioned in our terminal.

Sans titre

Sans titre

Sans titre

Youpiiiii! Prisma graphql API is up and running.

Happy Business People Excited Party Yay

Now let’s see how we got all this. Remember two files have been created:

  • datamodel.graphql

    type User {
    id: ID! @unique
    name: String!
    }
  • prisma.yml

    endpoint: https://eu1.prisma.sh/max237-27f373/blog01/dev
    datamodel: datamodel.graphql

Now, remember I said earlier that the database layer, provide CRUD operations and real-time interaction with the database, this is generated based on the data model (datamodel.graphql content). The Prisma cloud now own our database and provide us with a performant and powerful CRUD and real-time operations. You can learn more about it here. In short, we don’t need to worry about database the only thing we can do is to define our data model in datamodel.graphql and Prisma does handle the rest for us, isn’t it cool!!!, of course, it is. This part covers the Prisma database layer, let’s dive into the application layer part and Prisma data bindings.

Step2: Setup our Graphql server and signup users using Prisma’s data bindings

Note that I will not go through the whole process if you want to know more hit here. In this session we are going to write a small application that allows us to sign up users from the Yoga Graphql server playground which is actually where we can test the application queries or mutations and how Prisma bindings is involved, we are going to see the difference in the data available in both Prisma API service playground and the graphql server playground. Okay, let’s start.

I have created the Graphql server using the Prisma’s tutorial. Well in the src/schema. graphql where the application logic lives I have written this:

# import User from './generated/prisma.graphql'
type Query {
  user(id: ID!): User
  users:[User!]!
}

type Mutation {
  signup(name: String!): User!
}

We can see that I am importing the User type from the Prisma graphql service (or Prisma API). Remember that Prisma service auto-generate CRUD and real-time operation for us based on the data model ( datamodel.graphql). Our data model at this point is the same, no changes have been made. From the application ( graphql server playground) we can:

  • query a user by passing its id as a parameter and will get back the user’s info
  • query all users, therefore, will get a list of users.

Sans titre

In addition, we can add or signup a user by passing the user’s name as a parameter

And how do we make it work?

source

Well, we need to write our resolvers and bind it to Prisma’s auto-generated resolvers. In short, we need to assign Prisma API some tasks to do for us via Prisma bindings. Let’s implement it. This is what Prisma binding looks like.

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

Remember the content of our schema.graphql. There, we had two queries and one mutation. This is where we are actually implementing those queries and mutation. Chill let me explain what is going on. We have a resolvers JavaScript object that contains two fields: Query: where we implement our queries Mutation: where we implement our mutations Note that in our resolvers we are not making any query to the database instead we are telling Prisma to do it for us by using the famous Prisma bindings. I hope you have noticed the context.prisma in all our resolvers right!!. We use :

  • Context.prisma.query.queryname, to delegate the query to the Prisma API along with some parameters.
  • Context.prisma.mutation.muttationName, to delegate the mutation to the Prisma API along with some parameters. You can go more in depth by visiting prisma’s website. The full code for this is available on Github.

This concludes the post. So far we covered Prisma’s architecture and Prisma binding. Thanks hope this helps you to have a picture of what Prisma is.

Enjoyed this post? Receive the next one in your inbox!
Mr Toumi
Toumi Maximilien

Max eats, drinks and sleeps technology

Copyright © 2018 Tech47.