Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using @nestjs/graphql to create nested queries using @ResolveProperty and @Resolvers

Referencing the type-graphql sample repo in the NestJS repository here I am wondering how to create two more layers deep in the query.

Currently it is setup to query recipes, I was able to add another @ObjectType class

@ObjectType()
export class Author {
  @Field(type => Int)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;
}

and created a @ResolveProperty inside the Recipe Resolver with:


  @ResolveProperty('author', type => Author)
  async getAuthor(@Parent() recipe) {
    console.log('Resolver auth in recipe', recipe);
   // This will be a database call, just mocking data for now.
    return Promise.resolve({ id: 1, firstName: 'john', lastName: 'smith' });
  }

This all works fine (I also created a seperate resolver for Author but it is not my base query so I am not includng it), using this GraphQL query

{
  recipe(id: "1") {
    title,
    author {
      firstName
    }
  }
}

This query returns

{
  "data": {
    "recipe": {
      "title": "1",
      "author": {
        "firstName": "john"
      }
    }
  }
}

as it should. My question now is how do I add another level? I tried to create a "Publisher" ObjectType

@ObjectType()
export class Publisher {
  @Field(type => Int)
  id: number;
}

But no combination of creating resolvers or adding ResolveProperty in the Author and Recipe resolvers made it work. Where am I supposed to put the resolver code so that when GraphQL resolvers the Author object it will also resolve the associated Publisher info.

My goal is to get it so that a query such as:

{
  recipe(id: "1") {
    title,
    author {
      firstName,
      publisher: {
         id
      }
    }
  }
}

would return

{
  "data": {
    "recipe": {
      "title": "1",
      "author": {
        "firstName": "jay",
        "publisher": {
           id: 4        
        }
      }
    }
  }
}

Not sure if I am thinking about this wrong but this seems to be a key idea im missing to be able to expand on it! Thank you.

like image 271
Jay Bell Avatar asked Nov 07 '22 17:11

Jay Bell


1 Answers

You would basically just define an AuthorResolver that describes, how you would "work" with the Author. Within this AuthorResolver you would have a @ResolveProperty decorated method, to resolve your publisher property, like so:

// author.resolver.ts
@ResolveProperty('publisher', type => PublisherObjectType, {})
async resolvePublisher(@Parent() parent: AuthorEntity) {
   return parent.getPublisher(); // this method would return your Publisher!
}

Note that you need to create your own PublisherObjectType (with respective decorators) and make it available..

like image 80
zorn Avatar answered Nov 14 '22 21:11

zorn