Getting Started with Yoga and Prisma for Building GraphQL Servers
Publikováno: 7.6.2018
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 ...
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:
- 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:
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:
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
Once deployment is complete, on the Prisma Cloud you can see a list of your deployed services:
To open the GraphQL API and start sending queries and running mutations, run the command:
prisma playground
Updating Schema
When the scotch-prisma-demo
folder was created, two files were created in the folder
prisma.yml
- containing theendpoint
anddatamodel
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 graphgql-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:
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.