question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

I’m submitting a…


[ ] Regression 
[ ] Bug report
[x] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

No possibility to create nested resolvers (or no info in the docs).

Expected behavior

Possibility to make nested resolvers (and/or appropriate info in the docs).

Minimal reproduction of the problem with instructions

In the docs we have example how to make Posts property resolver on Author Resolver. But we don’t have any info, how to make nested resolver on those posts. For example - we’d like to lazy fetch (only when someone requests the field) posts statistics. Seems like this isn’t possible at the moment?

@Resolver(of => Author)
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
    private readonly statsService: StatsService, // hypothetical, low-performing service
  ) {}

  @Query(returns => Author)
  async author(@Args({ name: 'id', type: () => Int }) id: number) {
    return await this.authorsService.findOneById(id);
  }

  @ResolveProperty()
  async posts(@Parent() author) {
    const { id } = author;
    return await this.postsService.findAll({ authorId: id });
  }

  // This does NOT work. Nor is mentioned anywhere in the docs.
  @ResolveProperty()
  async stats(@Parent() post) {
    const { id } = post;
    return await this.statsService.getPostStatistics({ postId: id });
  }
}

So, is this possible in any way? If not, would a feature request like this be acceptable?

What is the motivation / use case for changing the behavior?

One of the biggest advantages of graphQL is lazy fetching nested fields (graph-like connections). Current implementation of graphQL decorators probably doesn’t allow creating nested resolvers.

Edit: Found similar question here: #162, but no luck with an answer yet. 😦

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:8

github_iconTop GitHub Comments

5reactions
krislefebercommented, Nov 16, 2019

You would end up with something like this.

First define the classes. Notice that there are no decorators on the object references. We instead add the mappings to that object in the Resolver.

@ObjectType()
class Level1 {
    @Field(() => ID)
    level1Field: string;
    level2: Promise<Level2>;
}

@ObjectType()
class Level2 {
    @Field(() => ID)
    level2Field: string;
    level3: Promise<Level3>;
}

@ObjectType()
class Level3 {
    @Field(() => ID)
    level3Field: string;
} 

In the first resolver, add the initial query for a search by id. We also add the getLevel2Property function, which tells graphql how to connect the two objects.

@Resolver(Level1)
class Level1Resolver {

    @Query(() => Level1, {
        name: 'Level1',
    })
    public async getLevel1(@Args('id') id: string): Promise<Level1> {
        const level1 = new Level1();
        level1.level1Field = id;
        return level1;
    }

    @ResolveProperty(() => Level2, {
        name: 'Level2',
    })
    public async getLevel2Property(@Args('optionalParam') optionalParam: string, @Parent() parent: Level1): Promise<Level2> {
       // this can be whatever logic you have to connect the two entities
        const level2 = new Level2();
        if (optionalParam) {
            level2.level2Field = optionalParam;
        }
        return level2;
    }
}

In the level 2 resolver, we need to add the mapping to Level3. Once again, the code inside getLevel3Property can be whatever you want.

@Resolver(Level2)
class Level2Resolver {

    @ResolveProperty(() => Level3, {
        name: 'Level3',
    })
    public async getLevel3Property(@Args('optionalParam') optionalParam: string, @Parent() parent: Level2) {

        const level3 = new Level3();
        if (optionalParam) {
            level3.level3Field = optionalParam;
        }
        return level3;
    }
}

Let me know if that makes sense. Thanks

2reactions
j3bb9zcommented, Nov 14, 2019

@krislefeber I just want to make possible query like this one:

{
    Level1(id: "someId") {
        level1Field
        Level2(optionalParam: "optional") {
            level2Field
            Level3(optionalParam: "optional") {
                level3Field
            }
        }
    }
}

It is perfectly fine, to have it in separate resolver classes… but is it possible to nest it like this?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Nested GraphQL Resolvers & Separating Concerns
Nested GraphQL Resolvers & Separating Concerns ... Two approaches to implementing separation of concerns and better cohesion of operations in your GraphQL schema....
Read more >
Resolvers - Apollo GraphQL Docs
A resolver is a function that's responsible for populating the data for a single ... After you return an array, Apollo Server executes...
Read more >
How to create a nested resolver in apollo graphql server
To create a "nested" resolver, simply define the resolver on the return type of the parent field. In this case, your authorQueries field ......
Read more >
Resolving nested queries in GraphQL using Apollo Server
Let us look into how we can do this using nested queries in GraphQL. ... We only need to create a resolver for...
Read more >
Nested Resolvers and Shared Arguments | GraphQL Kotlin
Nested Resolvers and Shared Arguments. There are a few ways in which shared arguments can be accessed from different resolver levels.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found