Forwarding to Prisma
Overview
Prisma bindings are commonly used for implementing the application layer in GraphQL servers. Next to providing business logic and other functionality such as authentication and authorization, the responsibility of the application layer is to transform Prisma's generic CRUD API into a domain-specific API that fits the needs of your client applications.
Sometimes it might be the case that you don't actually need to transform an operation from your Prisma API but instead simply want to proxy the exact same operation from Prisma in your application layer.
In these cases, you can use forwardTo
from the prisma-binding
library. It has the following interface:
forwardTo(bindingName: string)
forwardTo
depends on the resolver arguments context
and info
. Therefore, it can only be used inside a resolver function, not in Node scripts or other applications where Prisma bindings are used outside the context of a resolver function.
The bindingName
argument refers to the key which holds the Prisma
binding object on context
. For example, assume you instantiate your GraphQLServer
as follows:
const server = new GraphQLServer({
typeDefs: 'src/schema/schema.graphql',
resolvers,
context: {
db: new Prisma({
typeDefs: 'src/generated/prisma.graphql',
endpoint: 'http://localhost:4466',
}),
},
})
Then db
is the bindingName
:
const resolvers = {
Mutation: {
createPost: forwardTo('db'),
},
}
In the future, it is planned to implement the forwardTo
directive to reduce even more boilerplate and save the resolver implementation for an operation altogether. Join the discussion on GitHub to learn more.
Example
Assume your Prisma API is based on the following data model:
type User {
id: ID! @unique
name: String!
}
Your Prisma API will expose the following users
query:
type Query {
users(
where: UserWhereInput
orderBy: UserOrderByInput
skip: Int
after: String
before: String
first: Int
last: Int
): [User]!
}
If you now want to expose the exact same query on the application layer, you can use forwardTo
.
Without forwardTo
Before demonstrating how forwardTo
can be used for that use case, let's quickly run through what it would look like if you were to implement this functionality without forwardTo
.
Application schema (commonly called schema.graphql
):
# import Post, PostWhereInput, PostOrderByInput from "prisma.graphql"
type Query {
posts(
where: PostWhereInput
orderBy: PostOrderByInput
skip: Int
after: String
before: String
first: Int
last: Int
): [Post!]!
}
Resolver implementation (e.g. index.js
):
const resolvers = {
Query: {
posts: (root, args, context, info) => {
return context.prisma.query.posts(args, info)
},
},
}
With forwardTo
To reduce the boilerplate of the approach above, you can use forwardTo
. The application schema is defined in the same way as before:
Application schema (commonly called schema.graphql
):
# import Post, PostWhereInput, PostOrderByInput from "prisma.graphql"
type Query {
posts(
where: PostWhereInput
orderBy: PostOrderByInput
skip: Int
after: String
before: String
first: Int
last: Int
): [Post!]!
}
Inside the posts
resolver you're now using forwardTo
instead of explicitly invoking the posts
binding function.
Resolver implementation (e.g. index.js
):
const resolvers = {
Query: {
posts: forwardTo('prisma'),
},
}