graphql-nexus / nexus-plugin-prisma

Deprecated
MIT License
828 stars 118 forks source link

Provide built-in helper to convert nulls to undefined from GraphQL args to Prisma Client #863

Open Weakky opened 4 years ago

Weakky commented 4 years ago

Description

Historically, null was accepted for every Prisma Client args (pagination, filters etc..) because GraphQL does accept null | undefined for nullable fields. Since a couple of versions, the Prisma Client removed the acceptance of null for some of its args because null has actual semantic value in some cases.

When using Nexus, this can create some issues. Because nullable input object type fields are all typed as null | undefined, in some cases you might no longer be able to forward the args from your resolver down to the Prisma Client.

Notes

Early proposals

1) Small type-safe helper to convert null values to undefined

Example:

resolve(root, args, ctx) {
  return ctx.prisma.user.findMany(convertNullsToUndefined(args))
}
P4sca1 commented 4 years ago

Hey, this feature would be very helpful!

HendrikJan commented 4 years ago

I think I am currently experiencing the described problem:

t.list.field('AcademicYears', {
    type: 'AcademicYear',
    args: {
        where: 'AcademicYearWhereInput',
        first: intArg({ required: false }),
        last: intArg({ required: false }),
    },
    resolve: async (root, { where }, ctx) => {
        return ctx.prisma.academicYear.findMany({
          where, // <-- error: Type 'null' is not assignable to type 'AcademicYearWhereInput | undefined'
        })
    },
})

Is there currently a workaround?

ahmedosama5200 commented 3 years ago

Having the same issue here, too

Fi1osof commented 3 years ago

+1

ahmedosama5200 commented 3 years ago

They are rewriting the plugin from scratch #1039 I hope they take this issue into consideration, It's really annoying

nenadfilipovic commented 3 years ago

+1

simonjoom commented 1 year ago

Yeah i ve got the exact same problem using a version of nexus-plugin-prisma and the last prisma3.,

Prisma do explain well the behavior between null and undefined https://www.prisma.io/docs/concepts/components/prisma-client/null-and-undefined

In my side i decided to remove all field null, seems a better option than mutate to undefined because there is some difference of treatment for conditionals: https://www.prisma.io/docs/concepts/components/prisma-client/null-and-undefined#the-effect-of-null-and-undefined-on-conditionals

i did create a empty function to remove any nulls from any field from the object coming from nexus

    function removeEmpty(obj) {
            return Object.entries(obj)
              .filter(([_, v]) => v != null)
              .reduce(
                (acc, [k, v]) => ({ ...acc, [k]: v === Object(v) ? removeEmpty(v) : v }),
                {}
              );
          }

import type {Prisma} from "./../../node_modules/.prisma/client/index.js"
....
resolve(root, args, ctx) {
//any function remove any typescript error coming from bad typings of mutate args so we won t be able to use typescript in this stage for any fields 
// as after the function removeEmpty the typing of args will be always 'any'  so do it just before to send down to prisma.. like below:

let myarg:Prisma.UserFindManyArgs={where:args.where,skip:args.skip} // to check syntax with typescript

//then
  return ctx.prisma.user.findMany(removeEmpty(myarg)) 
}

well if you don t want to work with typescript to help your code writing, just force any from the object and we do need anything else:

let myarg:any={where:args.where,skip:args.skip}
  return ctx.prisma.user.findMany(myarg) 
dennohpeter commented 5 months ago

This is useful, however, how can this be done without losing type(s) checking in typescript ?