Nexus field resolver parent type is not nullable

1.1k views Asked by At

Anyone can query user with any fields they want, but gor some reason q_id field resolver parent type includes all fields. How can i fix parent type and make it nullable for each field?

I want to load q_id only when q_is_public (it works, but i need to keep in mind that parant fields can be undefined).

import { extendType, inputObjectType, objectType, arg } from '@nexus/schema'

export const User = objectType({
  name: 'User',
  definition(t) {
    t.model.id()
    t.model.nickname()
    t.model.q_is_public()
    t.field('q_id', {
      type: 'Int',
      nullable: true,
      resolve: (parent) => {
        /*
        parent type is:
        {
          id: number;
          nickname: string;
          q_is_public: boolean;
        }

        parent type actual:
        {
          id?: number;
          nickname?: string;
          q_is_public?: boolean;
          q_id?: boolean;
          ... and so on, what user requested
        }
        */
        return parent?.q_is_public ? parent?.q_id : null
      },
    })
  },
})

const FindOneUserInput = inputObjectType({
  name: 'FindOneUserInput',
  definition(t) {
    t.int('id', { required: true })
  },
})

export const FindOneUser = extendType({
  type: 'Query',
  definition(t) {
    t.field('findOneUser', {
      type: 'User',
      nullable: true,
      args: { where: arg({ type: FindOneUserInput, required: true }) },
      resolve: async (_parent, { where }, { db }, _info) => {
        // here will be used pal.select instead all fields load, to load only selected fields
        const res = await db.user.findOne({
          where,
        })

        return res
      },
    })
  },
})
2

There are 2 answers

0
Mickaël Boidin On

It's normal, your query resolver is probably using an ORM or DB client that retrieve all user data (colmuns) including these you don't need/want. That's why your parentis "full of unwanted data". But it doesn't matter, what matter is which field you are exposing (In your case id, nickname and q_is_public). No one "outside" your API can access the non-exposed data.

In other words, the user data you have in your parent argument is provided directly by your DB/ORM client. And your GraphQL server doesn't expose it all (depends on your t.model).

You can optimize your API by only requesting id, nickname, q_id and q_is_public colmuns from your DB. But if, in the future, you need to expose more field you will have to update your DB query to retrieve more columns.

0
ZiiMakc On

I think best option is to use nexus generated types to redefine type as Partial

resolve: (parent: DeepPartial<NexusTypesGen.NexusGenFieldTypes['User']>) => {}