lighthouse icon indicating copy to clipboard operation
lighthouse copied to clipboard

Ability to access the parent model in `@builder` directive

Open hosmelq opened this issue 5 years ago • 3 comments

What problem does this feature proposal attempt to solve?

I have the following schema

type Category {
  products: [Product!]!
    @builder(method: "App\\GraphQL\\Categories\\Builders\\OrderProducts")
    @belongsToMany(maxCount: 50, type: CONNECTION)
}

I would like to have access to the Category model within the builder because I have a field that specifies how the products are ordered within that Category.

At the moment I only have access to the builder.

Which possible solutions should be considered?

I don't know what would be the best solution for this.

hosmelq avatar Feb 20 '21 20:02 hosmelq

To enable this, we would have to pass the resolver arguments - in your case $root - to ArgumentSet::enhanceBuilder() and all functions below it. Such a change would be a lot of work and can not be implemented without significant breakage.

I do not plan to add support for this any time soon, but if you really want it you can give it a shot.

spawnia avatar Feb 22 '21 22:02 spawnia

I was checking the implementation of ArgumentSet::enhanceBuilder() and found that there are some directives that do not need the $root argument.

Maybe I can create a new interface to implement something like FieldBuilderDirectiveWithRoot with a method like handleFieldBuilder(object $builder, Model $root).

The $root model can be passed as a third parameter to the resolver to avoid breaking changes.

hosmelq avatar Feb 24 '21 23:02 hosmelq

If we were to change this, we should also pass along the other resolver arguments, not just $root. That way we won't have to extend this even further if other use cases pop up.

I thought of one special case to consider, where passing $root is somewhat ambiguous: builders for batched resolvers. For example, in a scenario like this:

type Post {
  comments(popular: Boolean @eq): [Comment!]! @hasMany
}

{
  posts {
    comments(popular: true) { ... }
  }
}

Assuming there are multiple posts, there are multiple instances of $root when resolving comments. However, Lighthouse optimizes the query through batch loading, which means there will only be a single query for comments and thus a single call to the EqDirective. There is no clear answer which of the parent posts should be the $root for that call.

spawnia avatar Feb 25 '21 07:02 spawnia