nexus-plugin-prisma icon indicating copy to clipboard operation
nexus-plugin-prisma copied to clipboard

Bring back `t.prismaType` on the v2

Open Weakky opened this issue 5 years ago • 10 comments

Description

One very appreciated feature is the current t.prismaType property (documented here: https://nexus.js.org/docs/database-access-with-prisma#tprismatype).

That feature is not possible anymore in the nexus-prisma v2, but we definitely want to bring it back as it enables a ton of more advanced use-cases.

Any proposal that'd be more idiomatic to the new API would be very appreciated 🙌

Weakky avatar Jun 24 '19 13:06 Weakky

The ability to do

const Query = prismaObjectType({
  name: 'Query',
  definition(t) {
    t.field('users', {
      ...t.prismaType.users,
      args: {
        ...t.prismaType.users.args,
        newArg: stringArg(),
      },
      resolve(root, args, ctx) {
        // Custom implementation
      },
    })
  },
})

is great and gives so much value to nexus-prisma1. As you said it enables tons of advanced use cases, and it also very enjoyable to use as it feels powerful and elegant. I would love to still have the ability to do that :

const Mutation = prismaObjectType({
    name: "Mutation",
    definition: t => {
        t.field("createUser", User.create(t.prismaType.createUser)) //Easily add custom logic by extending prismaType.createUser and over-writing args or resolver
        t.field("updateUser", { ...t.prismaType.updateUser }) //Quickly expose prismaType.updateUser
    }
})

//User.create
export const create = prismaCreateUser => ({
    ...prismaCreateUser,
    resolve: async (parent, args, ctx, info) => {
        const { something } = await asyncOperation(args.email)
        const user =  ctx.prisma.createUser({
             ...args, something
        })
        doSomething(user.id)
        return user
    }

Hebilicious avatar Jun 25 '19 10:06 Hebilicious

Really looking forward to being able to use the t.prismaType equivalent with Prisma2!

iherger avatar Jul 09 '19 04:07 iherger

This would be really useful for cases where you need to modify just a little bit the CRUD generated and avoid duplicating a lot of code.

For example, in this case, I only need to set an attribute with a value from the context and I have to do this:

export const UserMutations = extendType({
    type: 'Mutation',
    definition: t => {
        //t.crud.createOneClient();
        t.crud.updateOneClient()
        t.field('createClient', {
            type: 'Client',
            args: {
                name: stringArg(),
                email: stringArg(),
                idCardNumber: intArg(),
                idCardType: arg({ type: 'IDCardType' }),
                addresses: arg({
                    type: 'ClientCreateaddressesInput',
                }),
                phones: arg({ type: 'ClientCreatephonesInput' }),
            },
            resolve: (
                parent,
                { name, email, idCardNumber, idCardType, addresses, phones },
                ctx
            ) => {
                return ctx.photon.clients.create({
                    data: {
                        name,
                        email,
                        idCardNumber,
                        idCardType,
                        addresses,
                        phones,
                        createdBy: {
                            connect: { id: ctx.userInfo.id}
                        },
                    },
                })
            },
        })
    },
})

It's almost identical to the original crud. this kind of actions will be really frequent in any backend.

nicosampler avatar Sep 30 '19 16:09 nicosampler

While I originally thought that it's really important to have t.prismaType back, I now think that it's nice to have, but can also be done without too much effort otherwise.

In your example, you could do:

export const UserMutations = extendType({
    type: 'Mutation',
    definition: t => {
        t.field('createClient', {
            type: 'Client',
            args: {
                data: arg('ClientCreateInput'),
            },
            resolve: (_, args, ctx) => {
                return ctx.photon.clients.create({
                    data: { ...args, 
                        createdBy: {
                            connect: { id: ctx.userInfo.id}
                        },
                    },
                })
            },
        })
    },
})

iherger avatar Sep 30 '19 20:09 iherger

:+1: that is much shorter, but, you will have to replicate that for create/update and in more than one entity.

nicosampler avatar Sep 30 '19 22:09 nicosampler

Nexus plugins needs to be released for this to work.

Currently blocked by: https://github.com/prisma-labs/nexus/pull/236

Weakky avatar Oct 15 '19 17:10 Weakky

Hey @Weakky! Any update here?

zingerj avatar Mar 24 '20 06:03 zingerj

I'm upgrading my prisma1 codebase and was making use of this feature - would be keen to know of a workaround in the meantime? Perhaps something could be added to the nexus examples? Thanks!

homerjam avatar Apr 15 '20 15:04 homerjam

Note to self:

-      args: t.prismaType.createWorkspaceInvite.args,
+      args: {
+        data: arg({ type: 'WorkspaceInviteCreateInput' }),
+      },

homerjam avatar Apr 15 '20 16:04 homerjam

Note to self:

-      args: t.prismaType.createWorkspaceInvite.args,
+      args: {
+        data: arg({ type: 'WorkspaceInviteCreateInput' }),
+      },

I'd like to know whether this method can leverage the generated WhereInput types also?

In an effort to create a count query I tried the below but it has Type issues.

    t.int('countPosts', {
      args: {
        where: arg({
          type: 'PostWhereInput',
        }),
      },
      resolve(root, args, ctx, info) {
        return ctx.db.post.count({ where: args.where })
      },
    })

I'm hoping there is a nifty crud count method already available that I don't know about 🤞

toddpla avatar Sep 27 '20 20:09 toddpla