Hi @gcallsen and glad to see you trying out RedwoodJS!
You’ve stumbled upon a topic that we should definitely clarify in the docs and that’s the way GraphQL plays with the services.
In Redwood, a service method (e.g. technologyModelsWithRelations
) gets automatically mapped to a GraphQL resolver of the same name – and which you had defined in one of your sdl
files. Redwood also assembles all the sdl (aka types), the services (aka resolvers), directives, and other things like subscription and such to make a large schema. We let you work on the schema in pieces and “merge:” everything that the GraphQL server function needs.
GraphQL sees queries like
post {
id
title
authors {
id
name
}
}
as:
- get me the post
- get me the post’s authors
It will use the author
resolver and the author’s books resolver to fetch that. And yes, this could be two separate queries.
Now, even if in your Prisma query as part of the post
services you eager load and include the authors and even sort the authors by name, GraphQL won’t use that info but go back the the post’s authors resolver.
So, an example we can see if that books may not be sorted by title even though the author service is doing that.
Of course, you could replicate the sort logic in the post’s authors resolver … but there’s a better way.
If you eager load and include and sort the authors in your post service, you can “shortcut” in the posts’ authors resolver to ask – do I already have authors populated on my root object (ie, did post eager load and sort the authors I wanted already)? if, so no more work is needed and you can return the root as it doesn’t need to make another db call to fetch the post’s authors.
export const Post: PostRelationResolvers = {
authors: (_obj, { root }) => {
// shortcut and see if the root Post already has authors populated, and if so return them
// if the post service eager loaded and included and sorted, they will retain that filtering
if (root.authors) {
return root.authors
}
// otherwise you need to fetch them from the db
return db.post.findUnique({ where: { id: root?.id } }).authors()
},
}
We’ve been considering changing this in the default CRUD scaffolded services – and should document better.
However, with RSC and direct db fetching, this behavior will go away since what the service returns is what is returned.
Hope that helps.
I think you could try:
export const TechnologyModel: TechnologyModelRelationResolvers = {
technologyModelVersions: (_obj, { root }) => {
if (root.technologyModelVersions) {
return root.technologyModelVersions
}
return db.technologyModel
.findUnique({ where: { id: root?.id } })
.technologyModelVersions()
},
}
and let your service of the take 1 etc.
Let me know if that works – and if not, we can try something else.