You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Dec 19, 2019. It is now read-only.
Problem statement
All resolvers in Magento must implement Resolver interface, which in its turn forces the instance of \GraphQL\Deferred to be returned by each resolver. To be precise, Magento wrapper for deferred, \Magento\Framework\GraphQl\Query\Resolver\Value, must be returned.
/*** Fetches the data from persistence models and format it according to the GraphQL schema.** @param \Magento\Framework\GraphQl\Config\Element\Field $field* @param $context* @param ResolveInfo $info* @param array|null $value* @param array|null $args* @throws \Exception* @return Value*/publicfunction resolve(
Field$field,
$context,
ResolveInfo$info,
array$value = null,
array$args = null
) : Value;
The main reason for using deferred in GraphQL is to optimize performance by solving N+1 problem where it exists.
An example of valid deferred usage in Magento can be found in \Magento\CatalogGraphQl\Model\Resolver\Product::resolve.
In all other cases, when there is no need to solve N+1 problem, we end up with boilerplate code like:
$result = function () use ($data) {
return$data;
};
return$this->valueFactory->create($result);
Response type unification is one of the reasons why deferred was made the only possible return type for resolvers. However, after implementing more resolvers it became obvious that current design just adds unnecessary complexity to the resolver implementations. Proposed solution
In addition to deferred, allow scalars and arrays of scalars as return types for \Magento\CatalogGraphQl\Model\Resolver\Product::resolve.
It will also be easier to customize resolver with plugins, if it returns array/scalar instead of deferred object. Action items
Modify existing resolvers, which have boilerplate code and do not require solving N+1 problem
Change
$result = function () use ($data) {
return$data;
};
return$this->valueFactory->create($result);
with
return$data;
Document the decision and make sure that all new resolvers return deferred only when necessary. Can just mark PR with "requires-documentation" label to leave this part for Magento's documentation team.
The text was updated successfully, but these errors were encountered:
Problem statement
All resolvers in Magento must implement Resolver interface, which in its turn forces the instance of
\GraphQL\Deferred
to be returned by each resolver. To be precise, Magento wrapper for deferred,\Magento\Framework\GraphQl\Query\Resolver\Value
, must be returned.The main reason for using deferred in GraphQL is to optimize performance by solving N+1 problem where it exists.
An example of valid deferred usage in Magento can be found in
\Magento\CatalogGraphQl\Model\Resolver\Product::resolve
.In all other cases, when there is no need to solve N+1 problem, we end up with boilerplate code like:
Response type unification is one of the reasons why deferred was made the only possible return type for resolvers. However, after implementing more resolvers it became obvious that current design just adds unnecessary complexity to the resolver implementations.
Proposed solution
In addition to deferred, allow scalars and arrays of scalars as return types for
\Magento\CatalogGraphQl\Model\Resolver\Product::resolve
.It will also be easier to customize resolver with plugins, if it returns array/scalar instead of
deferred
object.Action items
Change
to
Also, replace boilerplate code in resolvers
with
The text was updated successfully, but these errors were encountered: