typescriptgraphqltypegraphql

What does the argument to @Resolver for type-graphql do?


Honestly, just curious, on the documentation website for type-graphql, they pass an argument to the @Resolver decorator. Here is the link to the page where it occurs: https://typegraphql.com/docs/getting-started.html (under the "Resolvers" heading).

I've also included their code snippet here:

@Resolver(Recipe)
class RecipeResolver {
  constructor(private recipeService: RecipeService) {}

  @Query(returns => Recipe)
  async recipe(@Arg("id") id: string) {
    const recipe = await this.recipeService.findById(id);
    if (recipe === undefined) {
      throw new RecipeNotFoundError(id);
    }
    return recipe;
  }

  @Query(returns => [Recipe])
  recipes(@Args() { skip, take }: RecipesArgs) {
    return this.recipeService.findAll({ skip, take });
  }

  @Mutation(returns => Recipe)
  @Authorized()
  addRecipe(
    @Arg("newRecipeData") newRecipeData: NewRecipeInput,
    @Ctx("user") user: User,
  ): Promise<Recipe> {
    return this.recipeService.addNew({ data: newRecipeData, user });
  }

  @Mutation(returns => Boolean)
  @Authorized(Roles.Admin)
  async removeRecipe(@Arg("id") id: string) {
    try {
      await this.recipeService.removeById(id);
      return true;
    } catch {
      return false;
    }
  }
}

My code still works without the argument to @Resolver so I'm sure it's not that important but I'm wondering what it's used for?


Solution

  • It's used in a @FieldResolver method.

    Field resolvers in TypeGraphQL are very similar to queries and mutations. Create them as a method on the resolver class, but with a few modifications. First, declare which object type fields we are resolving by providing the type to the @Resolver decorator:

    @Resolver(of => Recipe)
    class RecipeResolver {
     // queries and mutations
    }
    

    Then, create a class method (e.g., averageRating) that will become the field resolver. The method is marked with the @FieldResolver() decorator. Also, decorate the method parameters with the @Root decorator in order to inject the recipe object:

    @Resolver(of => Recipe)
    class RecipeResolver {
      // queries and mutations
    
      @FieldResolver()
      averageRating(@Root() recipe: Recipe) {
        const ratingsSum = recipe.ratings.reduce((a, b) => a + b, 0);
        return recipe.ratings.length ? ratingsSum / recipe.ratings.length : null;
      }
    }