Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prisma plugin select with expose does not work properly if fetched through resolveReference #1321

Open
macrozone opened this issue Oct 22, 2024 · 5 comments
Labels
documentation Improvements or additions to documentation good first issue Good for newcomers help wanted Extra attention is needed

Comments

@macrozone
Copy link

macrozone commented Oct 22, 2024

Consider a federated graph where in one graph you declare an entity like this:



export const ProjectRef = builder.prismaObject("Project", {
  select: { // to load only the necessary data, you can select the fields you need
    id: true,
    name: true
  },
  fields: (t) => ({
    id: t.exposeID("id"),
    name: t.exposeString("name"),
    slug: t.exposeString("slug") // exposeString automatically selects the exposed variable, so you don't need to explicitly add this to `select`
  }),
});


builder.asEntity(ProjectRef, {
  key: [
    builder.selection<{ id: string }>("id"),
  ],
  resolveReference: (key) => {
    return prisma.project.findUnique({
      where: {
        id: key.id
      },
      // pothos correctly sets the type so i have to set the same `select` as in the objectRef
      select: {
        id: true,
        name: true
      }
    });
  },
});

If this entity is resolved in another graph and therefore resolveReference is called, slug will yield an error:

 "Cannot return null for non-nullable field Project.slug.",

It turns out that t.exposeString("slug") does not properly append the select in this case.

Workarounds:

  • not using expose, but instead a normal field resolver:
slug: t.string({
      select: {
        slug: true,
      },
      resolve: (parent) => parent.slug,
    }),
  • not using select in the resolveReference call. That means you will lose the efficiency gains there
@hayes
Copy link
Owner

hayes commented Oct 22, 2024

can you try this instead:

import { queryFromInfo } from '@pothos/plugin-prisma'

builder.asEntity(ProjectRef, {
  key: [
    builder.selection<{ id: string }>("id"),
  ],
  resolveReference: (key, ccontext, info) => {
    return prisma.project.findUnique({
      ...queryFromInfo({ context, info, typeName: 'Project' }),
      where: {
        id: key.id
      },
    });
  },
});

@hayes
Copy link
Owner

hayes commented Nov 4, 2024

Going to close this since I haven't heard back. Feel free to re-open the issue if you are still having issues after trying the above

@hayes hayes closed this as completed Nov 4, 2024
@macrozone
Copy link
Author

hey @hayes, sorry for the late response. Thank you for your solution.

this works, but I think its worth documenting, since its a pitfall that isn't obvious to spot. (also the passed typeName isn't typed, so its possible to make a typo there)

@hayes
Copy link
Owner

hayes commented Nov 5, 2024

A PR to update the docs would be more than welcome!

I can't think of a good way to improve the typing of the typename here without deeply coupling the prisma and federation plugins, but open to suggestions.

@hayes hayes reopened this Nov 5, 2024
@hayes hayes added documentation Improvements or additions to documentation help wanted Extra attention is needed good first issue Good for newcomers labels Nov 5, 2024
@macrozone
Copy link
Author

@hayes will do, sorry for the dealy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants