If I define:
export const UserMutation = extendType({
type: "Mutation",
definition(t) {
t.crud.createOneUser({alias: 'signUp'})
},
})
then signUp mutation will be generated along with UserCreateInput type.
But if I need to customise the signUp mutation, I need to do something like:
export const UserMutation = extendType({
type: "Mutation",
definition(t) {
t.field("signUp", {
type: "Event",
args: {
data: arg({type: "EventCreateInput"})
},
resolve: async (mutation, {data}, context: Context) => {
...
},
})
},
})
But if I do so, then UserCreateInput is not generated anymore. Thus, I need to redefine it manually.
This type is pretty complicated to define it manually. It would be great, if nexus generate it even if t.crud.createOneEvent() is not called, but, for example, if it's just mentioned as arg({type: "EventCreateInput"}).
Currently, to bypass the issue, I need to define _createUser mutation:
t.crud.createOneUser({alias: '_createUser'})
and then deny access to it by graphql shield:
_createUser: deny,
This way UserCreateInput is autogenerated, and I can use it in my custom mutation:
export const SignUpMutation = mutationField("signUp", {
type: "Authentication",
args: {
data: arg({type: "UserCreateInput"})
},
resolve: async (parent, {data}, context: Context) => {
...
},
})
Hey @victordombrovskiy thanks for this great feedback and example. This is a great example of how our tools are currently not scaling / not flexible enough. As you point out, at one point you cannot decompose and recompose but have to restart from scratch, essentially. This is not want we think a good dx looks like.
We will look more closely at the DSL in October / November. Meanwhile any perspective you want to share on your ideal type def building blocks API please do! 馃檹
Thanks for raising that limitation! Nexus-prisma V1 didn't have it (with prismaInputObjectType), but in our effort to simplify the mental model and reduce some magic, we left that issue.
As input types have normalized & predictable names, we could probably have a t.something() in inputObjectType() to help you create your own input types based on the ones that nexus-prisma generates for you.
export const UserCreateInput = inputObjectType({
name: 'UserCreateInput',
definition(t) {
t.something.field1()
t.something.field2()
}
})
But if we go this way, we have to be very careful about the naming we choose for something to keep the same mental model as we have now
Another way might also be through something like t.prismaType (which was available on nexus-prisma v1)
https://github.com/prisma/nexus-prisma/issues/303
https://nexus.js.org/docs/database-access-with-prisma#tprismatype
Related to #352
Would it be useful if custom resolvers could be passed? E.g.:
export const Mutation = mutationType({
definition(t) {
t.crud.createOneUser({
alias: 'signUp'
resolver(parent, args, ctx, info) {
// ...
}
})
},
})
I think that this is a very good idea.
here is a little work around that works for me
definition : (t)=>{
t.crud.createOneUser({
alias : 'signIn'
})
t.field("signIn",{
type : "User",
args : {
data : arg({
type: "UserCreateInput"
})
},
resolve : async (_, {data}, ctx ) =>{
var computedField = ... (Some logic)
return ctx.photon.users.create({
data :{ ...data!, computedField}
})
}
})
}
if you use shield, don't forget to change mutation name by it's alias in the rules
Most helpful comment
Would it be useful if custom resolvers could be passed? E.g.: