Lighthouse组合使用limit与paginate指令时触发类型报错问题
问题根因
执行GraphQL查询时Lighthouse抛出如下错误:
Nuwave\Lighthouse\Pagination\PaginatorField::dataResolver():
Argument #1 ($root) must be of type
Illuminate\Contracts\Pagination\LengthAwarePaginator, array given,
called in
/code/vendor/nuwave/lighthouse/src/Schema/Directives/FieldDirective.php
on line 51
该问题由@limit与@paginate指令的逻辑冲突导致,触发条件固定为两个指令同时使用:移除查询中的limit:1参数,或将Schema中@paginate替换为@all时请求可正常执行,和当前使用的Lighthouse 5.48、Laravel 9.11版本无兼容性问题。
@paginate指令会自动将查询结果封装为LengthAwarePaginator分页实例,同时自动注册分页所需的count、page参数,返回结构自动生成paginatorInfo、data两个分页字段,不需要额外通过limit控制单页数量。- 手动添加的
@limit指令会在@paginate执行完成后,对已生成的分页结果做截取操作,最终返回普通数组而非分页器实例。后续解析paginatorInfo、data字段时,要求传入的根值必须是LengthAwarePaginator类型,接收到数组就会抛出上述类型错误。
复现用例
触发问题的查询代码:
query getLastPlayed{ requests( limit: 1 ) { paginatorInfo{ total hasMorePages } data { id media { title duration } requested_at } } }
触发问题的Schema定义:
type Request { id: ID! media: Media! @belongsTo requested_by: User @hasOne requested_at: DateTime! played_at: DateTime } type Query { requests( limit: Int @limit ): [Request!]! @paginate(defaultCount: 10) }
修复方案
直接移除Schema中自定义的limit参数与@limit指令,使用@paginate自带的count参数控制单页返回数量即可,修改后的查询如下:
query getLastPlayed{ requests( count: 1 ) { paginatorInfo{ total hasMorePages } data { id media { title duration } requested_at } } }
修改后的Query定义如下:
type Query { requests: [Request!]! @paginate(defaultCount: 10) }
注:Lighthouse中
@limit指令的设计适用场景是配合@all、@hasMany等返回普通集合的指令使用,本身不支持和分页类指令搭配,不属于版本bug。
内容的提问来源于stack exchange,提问作者xorinzor
相关产品推荐
相关产品推荐

