As far as I can tell it seems there is no clear explanation of how to resolve subselections on related fields with the Prisma Client beta. With Prisma bindings these related fields are passed along via the info argument. In Prisma Client we must create additional type resolvers with query for the subselections by passing in the root id and chaining for the subfield. This process, since it is quite different from Prisma bindings, should IMO be more thoroughly documented. This seems to be causing confusion for people migrating from Prisma bindings to Prisma Client.
Great point @marcaaron. We're still working on preparing more/better examples. Does this docs section help in the meanwhile?
Yes! The docs are very helpful to a point, but unfortunately there's no mention of the need to create resolvers for types. In the past you need only pass the info argument along but now it seems a separate resolver is needed. e.g. if you want to resolve a list of related posts on a user then you need a User resolver with a posts resolver as a subselection on a user query.
User: {
posts: async (root, args, context) => {
const posts = await context.prisma.user({id: root.id})
.posts()
return posts
}
}
Someone either new to Prisma client or familiar with prisma bindings alike might be utterly confused on how to resolve subselections.
+1. This is one of the most confusing parts of the Prisma Client currently.
@schickling, do you have any advice on how to best handle querying relation fields for lists with the new client? Since this is not possible with the new Fluent API, and $delegate
has been removed, what are the options?
Thank you for your work on this project!
EDIT: Reading the “Reading Data” docs, it looks like $fragment
might be the way to go for now.
const fragment = `
fragment UserWithLinks on User {
name
email
links {
description
url
}
}
`
const userWithPosts = await prisma.users().$fragment(fragment)
DOUBLE EDIT: The docs say $fragment
is meant to "exclude large unneeded fields". With this logic, wouldn't it make more sense for prisma.users()
to return the links relationship by default, and then use $fragment
to exclude fields, instead of using it to add fields like this this example?
Thanks a lot for your great feedback @marcaaron @danthareja! I understand how this can be confusing. We're currently working on updating the docs and adding more examples to make this more clear. Please bear with us for the moment. 🙏
So, from what I understand, if our server uses schema delegation there is currently no solution provided by prisma-client. We are to use to continue to use prisma bindings? What exactly is the point of prisma client then, if it seems to be less feature-complete than bindings? I guess I'm confused as I thought prisma-client was the replacement to bindings and that bindings was to be deprecated.
My issues were resolved with the $delegate
methods provided by prisma-client but that was removed. Can the prisma team explain the reasoning behind this sudden change? Communication is greatly desired as I had just spent hours migrating my server only for it to be broken without warning.
I have since writing this noticed that there are examples in the Getting Started section of the docs which I neglected to work through having some previous experience with prisma bindings. I think there just needs to be something added to the main reference as well.
Relevant thread on the forum for anyone still following this issue: https://www.prisma.io/forum/t/help-understanding-prisma-clients-value-proposition/4394/15
I have a problem with types related to the $fragments
function and the missing TypeScript documentation.
My problem is that when I'm using it like the example in the docs that the result will have the type {}
.
I know that it is possible to do $fragment<Type>()
but I couldn't find any generated User
type which also has the links
field with the Link[]
type.
Generally its great to see a more typed approach as we always hated the info as text piece.
However, Two issues iwth the new client that make it a no-go for us using it:
Lack of delegation
Without delegation ability the prisma client really destroys the hole graphql story. the one key reason to use prisma vs other dbs is that there was a way to pass through graphql querying info as it cust development time significantly if the client side dev can just decide to pull in more fields. One can always lock this down on the server but not having the ability makes the new client a no-go for us in development despite us loving the typesafety of it.
Lack of sub querying relational fields in lists
While using fragments allows to select the fields and relations one wants back. There is no option to do sub selection for fields ala, give me all users and their OPEN orders which is not a problem when using the playground.
This hides a significant capability from the users with no way to access it through the client.
Seems like this issue has improved quite a bit in the recent weeks. By now we've added quite a few more examples & explanations in the docs.
Additionally I've just open this API proposal to address the prior concerns. Would love your feedback in the linked issue.
With the prisma client, if you are about to fetch multiple relational fields, do you suggest to perform multiple queries like this:
const linksByUser = await prisma.user({ email: "[email protected]" }).links()
const votesByUser = await prisma.user({ email: "[email protected]" }).votes()
Or is $fragments
they way forward?
In my specific case I'd like to fetch I`d like to process one of the nested objects after creation in the resolver. Similar to this:
createItem: async (_, args, context, info) => {
var item = context.prisma.createItem({
name: args.input.name,
post: {
create: {
number: 0
}
}
}, info)
const postId = await item.post().id()
processPost(postId)
return item
}
But when the returned item
is awaited, it only returns the same value as postId
. How can this be resolved with the prisma client?
Most helpful comment
With the prisma client, if you are about to fetch multiple relational fields, do you suggest to perform multiple queries like this:
Or is
$fragments
they way forward?In my specific case I'd like to fetch I`d like to process one of the nested objects after creation in the resolver. Similar to this:
But when the returned
item
is awaited, it only returns the same value aspostId
. How can this be resolved with the prisma client?