Type-graphql: How can I query only relevant fields?

Created on 9 Jan 2020  路  5Comments  路  Source: MichalLytek/type-graphql

I have the following simple query, where the client can retrieve informations from all users.
For performance reasons, I would like to retrieve only those fields from the database that the user has requested. Currently all fields are fetched from the database, even the user has only requested the columns id and email.

@Resolver(of => User)
export class UserResolver {
  constructor(
    // constructor injection of a service
    private readonly userService: UserService
  ) {}

  @Query(returns => [User])
  async users(
    @Args() options: UserArgs
  ): Promise<User[]> {
// How can I get here the fields that the user has requested?
    var users = await this.userService.findAll(options);
    return users;
  }
}
{
  users {
    id
    email
  }
}
Question Solved

Most helpful comment

The short answer is: you can pull the graphql info object as an argument in your resolve function:

  @Query(returns => [User])
  async users(
    @Args() options: UserArgs,
    @Info() info: GraphQLResolveInfo
  ): Promise<User[]> {
      // Inspect the info object and check which fields are requested
    var users = await this.userService.findAll(options);
    return users;
  }
}

But I really doubt, that this is worth the work. Did you confirm, that your query is in fact taking too much time by tests and measurements?
Have you tested your theory that fetching less fields will increase performance by a noticeable amount? Or are you taking only preventive measures?

preemptive optimization is the root of all evil
Donald Knuth

All 5 comments

The short answer is: you can pull the graphql info object as an argument in your resolve function:

  @Query(returns => [User])
  async users(
    @Args() options: UserArgs,
    @Info() info: GraphQLResolveInfo
  ): Promise<User[]> {
      // Inspect the info object and check which fields are requested
    var users = await this.userService.findAll(options);
    return users;
  }
}

But I really doubt, that this is worth the work. Did you confirm, that your query is in fact taking too much time by tests and measurements?
Have you tested your theory that fetching less fields will increase performance by a noticeable amount? Or are you taking only preventive measures?

preemptive optimization is the root of all evil
Donald Knuth

Hi, thanks for your reply. I've also found out that there is an info object from the type GraphQLResolveInfo, but how can I extract now the fields that were requested? I've looked at the property fieldNodes but there weren't the fields that I was looking for.

Currently this is just a preventive measure and for testing the possibilities of type graphql/graphql.
Normally I'll always fetch all fields, but once I had also a table with over 10.000 entries (also with joins), where fetching only the relevant fields increased the performance by a noticeable amount.

@DevelGitH See #10

I posted a simple example here.

Thanks that helped :)

Was this page helpful?
0 / 5 - 0 ratings