Magento 2.3.4 开发返回产品列表的GraphQL自定义Resolver实现方法
Magento 2.3.4 自定义GraphQL Resolver 返回产品列表实现
适配前提
- 已完成基础GraphQL模块搭建,可正常返回字符串、数组等简单类型的resolver逻辑,证明模块的GraphQL注册链路无异常
- 直接复用Magento核心公开服务能力即可实现,不需要硬抄vendor目录下的内部装配逻辑
之前复现核心实现逻辑失败的核心原因:Magento核心的产品GraphQL Resolver将字段解析、权限校验、属性加载逻辑拆分到了十余个通过依赖注入装配的协同类中,直接抄类的依赖列表很容易出现参数不匹配、对象未实例化的问题,不需要逐行复现这部分内部逻辑。
可直接复用的代码实现
1. 声明GraphQL Schema定义
在你模块的etc/schema.graphqls文件中添加自定义查询的类型定义,直接复用Magento核心已定义好的标准类型,不需要重复编写产品字段结构:
type Query { customProductList( filter: ProductFilterInput @doc(description: "产品筛选条件") pageSize: Int = 20 @doc(description: "每页返回条数") currentPage: Int = 1 @doc(description: "当前查询页码") ): CustomProductListOutput @resolver(class: "YourVendor\\YourModule\\Model\\Resolver\\CustomProductListResolver") @doc(description: "自定义产品列表查询") } type CustomProductListOutput { total_count: Int @doc(description: "匹配筛选条件的产品总数量") items: [Product] @doc(description: "匹配的产品条目列表") page_info: SearchResultPageInfo @doc(description: "分页信息结构") }
2. 编写Resolver实现类
按照schema里声明的类路径,创建Resolver实现文件YourVendor/YourModule/Model/Resolver/CustomProductListResolver.php,注入核心封装好的产品查询服务,避免手动加载产品集合:
<?php declare(strict_types=1); namespace YourVendor\YourModule\Model\Resolver; use Magento\CatalogGraphQl\Model\Resolver\Products\Query\ProductQueryInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; class CustomProductListResolver implements ResolverInterface { /** * @var ProductQueryInterface */ private $productQuery; // 2.3.4版本兼容PHP7语法,不使用构造函数属性提升 public function __construct( ProductQueryInterface $productQuery ) { $this->productQuery = $productQuery; } /** * @inheritDoc */ public function resolve( Field $field, $context, ResolveInfo $info, ?array $value = null, ?array $args = null ) { // 入参合法性校验 if (isset($args['pageSize']) && $args['pageSize'] < 1) { throw new GraphQlInputException(__('pageSize 参数值必须大于0')); } if (isset($args['currentPage']) && $args['currentPage'] < 1) { throw new GraphQlInputException(__('currentPage 参数值必须大于0')); } // 调用核心标准化查询服务,自动完成权限校验、属性加载、关联字段解析前置准备 $searchResult = $this->productQuery->getResult( $args['filter'] ?? [], $args['pageSize'] ?? 20, $args['currentPage'] ?? 1, $info ); // 返回符合schema定义的结构化结果 return [ 'total_count' => $searchResult->getTotalCount(), 'items' => $searchResult->getProductsSearchResult(), 'page_info' => [ 'page_size' => $args['pageSize'] ?? 20, 'current_page' => $args['currentPage'] ?? 1, 'total_pages' => (int)ceil($searchResult->getTotalCount() / ($args['pageSize'] ?? 20)) ] ]; } }
关键注意事项
- 不要在Resolver中手动实例化
ProductCollection加载产品数据:核心Product类型挂载了价格、库存、分类、自定义属性等数十个关联字段的自动解析逻辑,手动加载集合传入基础数据会导致所有关联字段返回null - 如需扩展自定义筛选逻辑,仅需在调用
getResult前修改$args['filter']数组结构即可,不需要修改核心查询逻辑 - 代码编写完成后,执行
php bin/magento setup:upgrade、php bin/magento cache:clean graphql即可让schema生效,不需要额外的DI配置
内容的提问来源于stack exchange,提问作者wezzy
相关产品推荐
相关产品推荐

