Hi Prisma !
Thanks for your amazing work.
Is there a simple way to add a default filter in crud ?
I want to expose a crud, but using a pre-defined constraint.
For example, expose a Post crud with filtering enabled, but with a constraint owner == myself that is not exposed.
The user will be allowed to retrieve only it's own Posts and filter them by title or number of comments, etc.
The only way i found to achieve this, is to write the resolver by myself and reimplement all the filtering.
Maybe it's a feature request. A simple implementation can be done by extending the filtering options and pass a default filtering object that will be merged with that is provided by the user.
Hey @lvauvillier, can you share some example SDL of what you're asking for exactly?
I'm asking if nexus-prisma can solve this common problem:
model Account {
id String @default(cuid()) @id @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
email String @unique
name String
projects Project[]
}
model Project {
id String @default(cuid()) @id @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String
account Account
}
We have here an account that owns its projects.
My api require authentication, so I have a middleware that adds a currentAccount in the context.
I want to expose a root projects Query and allow filtering with the field name
export const Query = queryType({
definition(t) {
t.crud.projects({ filtering: { name: true }});
}
});
The problem here is that all projects are exposed to the user. I want to add a constraint:
{ where: { account: { id: ctx.currentAccount.id }}}
Extending the api to add constraints, will be a great time saver :
function currentAccountConstraint(ctx) {
return { id: ctx.currentAccount.id };
}
export const Query = queryType({
definition(t) {
t.crud.projects({ filtering: { name: true, account: currentAccountConstraint }});
}
});
Is this request make sense ?
Hey @lvauvillier 馃憢, thanks for that great FR.
While we have no solution to offer right now, we do have exciting ones that should come soon:
1) Encapsulating resolve
This solution is related to #303. Here's a code snippet that shows how you'd do it:
t.field('projects', {
...t.prisma.projects,
resolve(root, args, ctx) {
const customArgs = {...args, where: { id: getUserId(ctx) } }
return t.prisma.projects.resolve(root, customArgs, ctx)
}
})
2) Via middleware
Middlewares could basically allow you to transform the args just like I did above, but globally/on specific types/on specific fields of a type.
They are coming soon thanks to nexus plugins. There's an open PR on the nexus repo (https://github.com/prisma-labs/nexus/pull/242) that you can track to know when this will be available.
Hopefully that answers your question 馃檶
Thanks, the first one seems to be the best fit for my use case.
Is there a way to help?
I'll take a look into middleware/plugins also. Is this can replace what we can do with graphql-middleware ?
I'll take a look into middleware/plugins also. Is this can replace what we can do with graphql-middleware ?
Yes I think so, but not too familiar with graphql-middleware.
I want to implement something like that too so I'll have no need to pass User ID on my frontend and just compute on the server. @Weakky Is there any change on solutions to this issue?
Yeah, I'm running into this too. The main draw of nexus-prisma is how much boilerplate it can cut down on. The length of time from adding data to my database to having it exposed for clients can be very quick. The problem here is that the moment I need to do any kind of default filtering like this (which is quite common), I'm back to defining the whole operation manually.
Has anyone figured out a way around this? I'm finding that most solutions involve undoing the connection between nexus and Prisma.
Yes, this can now be done easily using custom resolvers:
t.crud.projects({
resolve: (root, { where, ...args }, ctx, info, originalResolve) => {
return originalResolve(
root,
{
...args,
where: {
...where,
account: {
id: ctx.token.sub
}
}
}
},
ctx,
info
);
}
});
Closing this now as it indeed seems like custom resolvers has solved the problem! 馃檶
Most helpful comment
Yeah, I'm running into this too. The main draw of nexus-prisma is how much boilerplate it can cut down on. The length of time from adding data to my database to having it exposed for clients can be very quick. The problem here is that the moment I need to do any kind of default filtering like this (which is quite common), I'm back to defining the whole operation manually.