-
-
Notifications
You must be signed in to change notification settings - Fork 164
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 object with self-referencing object #1358
Comments
You can use the variant api for this https://pothos-graphql.dev/docs/plugins/drizzle#variants This will allow you to define multiple types based on the same model, and then use t.variant to define fields that reference the same instance of that model |
sorry, those are the docs for the drizzle equivalent. Trying to track down why this is missing from the prisma docs. It used to be there, but I can't find it now |
Here's the correct doc: https://pothos-graphql.dev/docs/plugins/prisma/variants I'd recommend skimming through the whole prisma docs again. There was a lot missing, and there might be some other relevant docs that have been restored now |
@hayes thanks! I was able to implement it as described in the new docs. It seems to work as expected for simple queries, but it crashed when I tried using it with more complex queries – that had fragments, etc. It looks like it didn't include some of the fields in the prisma query. I'll try to reproduce it in a demo and create a separate issue in the future. |
Interesting. If you can find a way to reproduce it, that would be great! Can you double check that you are spreading the query argument into all your Prisma queries when using t.prismaField? That's one of the only ways I've seen this plugin error in the past |
This is not a demo yet, but just in case it's useful, here's a simplified version of how it's being implemented: const User = builder.prismaNode("User", {
id: { field: "id" },
select: { id: true },
fields: (t) => ({
id: t.exposeID("id"),
name: t.exposeString("name", { nullable: false }),
}),
});
const UserAddress = builder.prismaObject("User", {
variant: "UserAddress",
fields: (t) => ({
streetAddress: t.exposeString("address"),
city: t.exposeString("city"),
state: t.exposeString("state"),
}),
});
builder.prismaObjectField("User", "address", (t) => t.variant(UserAddress));
builder.queryFields((t) => ({
user: t.prismaField({
type: User,
args: {
id: t.arg.id({ required: true }),
},
resolve: async (query, _source, args) => {
return prisma.user.findFirst({ ...query, where: { id: args.id } });
},
}),
})); I noticed that if I query only for the user name, the "query" variable in the user resolver has the expected fields: query {
user(id: "...") {
name
}
}
However, if I query the address fields, the "query" variable is an empty object: query {
user(id: "...") {
name
address {
streetAddress
}
}
}
|
This seems indicative of User having a default select (not shown in your example) and Address not having a default selection, effectively resulting in a The selection for User would be id and name, but when its merged with the selection for Address, you select all columns. Not providing a select is how Prisma queries for all columns implicitly. The query you logged SHOULD return all columns, because it doesn't have a select block. Id be curious what the Prisma query returns, in this case. |
That's correct. I've updated my example to include that, and also changed it to use "prismaNode".
As you've mentioned, the prisma query seems to use the default selection, even though the the 'query' from the
I've tried the following, but the same behavior still seems to happen:
|
Also, not sure if that could help, but I also noticed that the issue does not happen if my node is nested in a connection: query {
product(id: "69652d36-3126-90a9-9c9a-dac35103f3e5") {
users {
edges {
node {
name
address {
streetAddress
}
}
}
}
}
} |
Can you log out the actual the query and result in the resolver. Based on what you are saying it sounds like prisma isn't doing the right thing. I suspect either there is something odd about your Prisma setup, or our understanding of the problem is off (eg, the original query is correct, but Pothos triggers a second query with a different selection) |
Oh, sorry it. Looks like you did log out the result... If that is the only query, and the query object really doesn't contain a select (as described in your earlier response) then Prisma isn't working as intended. Can you confirm that the query object still is an empty object? Sounds like you've changed a lot since then |
Makes sense, I'll investigate further and try to set up a proper demo when I have some time. Thanks for the support
I confirm that the query object is still an empty object.
Honestly, I didn't change much; the setup is just as I described here. The other things I mentioned were simply experiments to see if they would produce any different results. |
If I am understanding this correctly, then this is an issue on the prisma side. To be very clear: prisma.user.findFirst({ ...{ /* empty object */ }, where: { id: args.id } }) is returning an object with only the id. This isn't how prisma is supposed to work, so either there is a bug in prisma, or one of the previous assumptions is wrong |
I am using the Prisma Plugin and I would like to group some information from my model when defining my Prisma Object. I'll use an example to contextualize, but also help to follow up and open a PR if this is interesting.
I have a model that is defined as following:
However, in order to keep the address information organized, I'd like to expose it in the GraphQL API as such:
Currently, I'm achieving that with a "simple object" for my address, but then, the user 'address' field selects all the fields from the database:
However, oftentimes I only need to show the 'city', which ends up fetching all the other address fields. I'd like to understand if there is another way to do this that would prevent overfetching data.
The text was updated successfully, but these errors were encountered: