Goals
On this page, you will learn how to:
- Define a GraphQL schema for your GraphQL server
- Implement resolver functions using the Prisma client
- Use the GraphQL Playground to try out your GraphQL API
Configure project
grahpql-yoga
is a GraphQL server library based on Express.js. Add it to your project with the following command:
npm install --save graphql-yoga
Copy
Define GraphQL API
Every GraphQL API is based on a GraphQL schema that specifies all API operations and data structures. The schema is a contract between client and server.
Create a new file called schema.graphql
:
touch schema.graphql
Copy
To define the API operations, you need to specify the Query
and Mutation
types in your GraphQL schema - the following operations are examples for a simple blogging application:
type Query { publishedPosts: [Post!]! post(postId: ID!): Post postsByUser(userId: ID!): [Post!]! } type Mutation { createUser(name: String!): User createDraft(title: String!, userId: ID!): Post publish(postId: ID!): Post } type User { id: ID! email: String name: String! posts: [Post!]! } type Post { id: ID! title: String! published: Boolean! author: User }
Copy
The
Post
andUser
types are straightforward re-definitions of the models specified indatamodel.prisma
, except that the Prisma-specific directives have been removed.
Implement resolver functions
Here is how you implement the resolver functions for the six API operations defined in the GraphQL schema. Replace the current contents of index.ts
entirely with the following code snippet:
import { prisma } from './generated/prisma-client' import { GraphQLServer } from 'graphql-yoga' const resolvers = { Query: { publishedPosts(parent, args, context) { return context.prisma.posts({ where: { published: true } }) }, post(parent, args, context) { return context.prisma.post({ id: args.postId }) }, postsByUser(parent, args, context) { return context.prisma .user({ id: args.userId, }) .posts() }, }, Mutation: { createDraft(parent, args, context) { return context.prisma.createPost({ title: args.title, author: { connect: { id: args.userId }, }, }) }, publish(parent, args, context) { return context.prisma.updatePost({ where: { id: args.postId }, data: { published: true }, }) }, createUser(parent, args, context) { return context.prisma.createUser({ name: args.name }) }, }, User: { posts(parent, args, context) { return context.prisma .user({ id: parent.id, }) .posts() }, }, Post: { author(parent, args, context) { return context.prisma .post({ id: parent.id, }) .author() }, }, }
Copy
Each resolver invokes a method on the Prisma client instance which is called prisma
and attached to the context
object.
One of the core benefits of GraphQL is its strongly typed schema. To leverage the full power of the schema, you should ensure that your resolvers are entirely type-safe as well. Check out graphqlgen
, a code-generation tool that helps you build type-safe GraphQL servers.
Configure your GraphQL server
Now you need to instantiate the GraphQLServer
from the graphql-yoga
library and pass the GraphQL schema along with its resolver functions. You're also attaching the imported prisma
client instance to the context
so that the resolvers can access it.
Add the following code snippet to the bottom of index.ts
:
const server = new GraphQLServer({ typeDefs: './schema.graphql', resolvers, context: { prisma, }, }) server.start(() => console.log('Server is running on http://localhost:4000'))
Copy
Explore the GraphQL API in a Playground
The GraphQL API of your application layer now exposes the six operations defined in schema.graphql
.
To test these operations, navigate your browser to http://localhost:4000
where a GraphQL Playground is running.
A GraphQL Playground is an interactive GraphQL IDE that lets you explore the operations of GraphQL API. You can click the green SCHEMA-button at the right edge of the Playground window to view the auto-generated documentation for your GraphQL API.
Here are a few sample queries and mutations you can send to explore the API.
mutation { createUser(name: "Jane") { id } }
Copy
In some snippets, you need to replace the
__USER__ID__
or__POST_ID__
placeholder with the ID of an actual user or post.