nexus-prisma
nexus-prisma
is a plugin for bridging Prisma and Nexus. It extends the Nexus DSL t
with .model
and .crud
making it easy to expose Prisma models and operations against them in your GraphQL API. The resolvers for these operations (pagination, filtering, ordering, and more), are dynamically created for you removing the need for traditional ORMs/query builders like TypeORM, Sequelize, or knex. And when you do need to drop down into custom resolvers a Photon instance on ctx
will be ready to serve you, the same great tool nexus-prisma
itself bulids upon.
Examples
You can find runnable examples in the examples folder. The following are isolated snippets to give you a sense for the DSL.
Exposed Prisma Model
Exposing one of your Prisma models in your GraphQL API
objectType({
name: 'Post',
definition(t) {
t.model.id()
t.model.title()
t.model.content()
},
})
Simple Computed Fields
You can add (computed) fields to a Prisma model using the standard GraphQL Nexus API.
objectType({
name: "Post",
definition(t) {
t.model.id()
t.model.title()
t.model.content()
t.string("uppercaseTitle", {
resolve({ title }, args, ctx) {
return title.toUpperCase(),
}
})
},
})
Complex Computed Fields
If you need more complicated logic for your computed field (e.g. have access to some information from the database), you can use the photon
instance that's attached to the context and implement your resolver based on that.
objectType({
name: 'Post',
definition(t) {
t.model.id()
t.model.content()
t.string('anotherComputedField', {
async resolve({ title }, args, ctx) {
const databaseInfo = await ctx.photon.someModel.someOperation(...)
const result = doSomething(databaseInfo)
return result
}
})
}
})
Renamed Prisma Model Fields
objectType({
name: 'Post',
definition(t) {
t.model.id()
t.model.content({ alias: 'body' })
},
})
Exposed Reads on Model
By default we expose only pagination. Ordering and filtering must be explicitely enabled because of the performance overhead that they might cause.
queryType({
definition(t) {
t.crud.post()
t.crud.posts({ ordering: true, filtering: true })
},
})
Exposed Writes on Model
queryType({
definition(t) {
t.crud.createPost()
t.crud.updatePost()
t.crud.deletePost()
},
})
Exposed Customized Reads on Model
If you wish to only expose some filters or orders, you can specify so on the model.
queryType({
definition(t) {
t.model.posts({
filtering: { id: true, title: true },
ordering: { title: true },
})
},
})
Exposed Model Writes Along Side Photon-Resolved Fields
mutationType({
definition(t) {
t.crud.createUser()
t.crud.updateUser()
t.crud.deleteUser()
t.crud.deletePost()
t.field('createDraft', {
type: 'Post',
args: {
title: stringArg(),
content: stringArg({ nullable: true }),
},
resolve: (parent, { title, content }, ctx) => {
return ctx.photon.posts.createPost({ title, content })
},
})
t.field('publish', {
type: 'Post',
nullable: true,
args: {
id: idArg(),
},
resolve(parent, { id }, ctx) {
return ctx.photon.posts.updatePost({
where: { id },
data: { published: true },
})
},
})
},
})