Laravel Lighthouse自定义带参数GraphQL查询及调试问询
在基于Laravel(版本9.48.0)与Lighthouse(版本6.6)的项目中,需要创建带有过滤条件、输出字段自定义格式化的自定义GraphQL查询,已执行以下操作:
- 查看Lighthouse命令:
php artisan lighthouse
- 创建自定义查询:
php artisan lighthouse:query Items
- 修改
graphql/item.graphql文件:
extend type Query { # 我认为需要移除@paginate指令 # items [Item!]! @paginate(defaultCount: 10) items: [Item!] }
- 发送带参数的查询请求:
{ items (filterByStatus: 'a' ) { id name } }
但GraphQL Playground无任何错误提示,Laravel端也无日志记录,该请求完全未触发;而不带参数的查询请求可正常运行:
{ items { id name } }
1. 声明GraphQL查询参数
你遇到的核心问题是没有在GraphQL schema中声明查询参数,导致带参数的请求被直接拦截。修改graphql/item.graphql,为items查询添加参数定义:
extend type Query { # 可选参数,不需要则去掉! items(filterByStatus: String!): [Item!] }
2. 在Resolver中处理参数
通过lighthouse:query生成的Resolver文件位于app/GraphQL/Queries/Items.php,修改resolve方法接收并使用参数:
<?php namespace App\GraphQL\Queries; use App\Models\Item; use GraphQL\Type\Definition\ResolveInfo; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; class Items { public function resolve($_, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) { $query = Item::query(); // 根据传入的过滤参数筛选数据 if (isset($args['filterByStatus'])) { $query->where('status', $args['filterByStatus']); } // 返回结果,可按需添加分页、排序逻辑 return $query->get(); } }
3. 自定义输出字段格式化
如果需要格式化输出字段,有两种常用方式:
- 模型访问器:在
Item模型中添加访问器,自动格式化字段
public function getNameAttribute($value) { // 示例:将name转为大写 return strtoupper($value); }
- 自定义字段Resolver:在GraphQL类型定义中指定解析方法
type Item { id: ID! name: String! @field(resolver: "App\\GraphQL\\Fields\\ItemName@resolve") }
然后创建app/GraphQL/Fields/ItemName.php实现解析逻辑:
<?php namespace App\GraphQL\Fields; use App\Models\Item; use GraphQL\Type\Definition\ResolveInfo; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; class ItemName { public function resolve(Item $root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) { return strtoupper($root->name); } }
验证Schema有效性
运行php artisan lighthouse:validate命令,检查.graphql文件是否存在语法错误、参数未声明等问题。开启Lighthouse调试日志
在.env中设置LIGHTHOUSE_LOG_LEVEL=debug,Lighthouse会将GraphQL请求的详细日志写入storage/logs/laravel.log,可查看请求是否被正确解析、参数是否传递。在Resolver中加日志
在Items.php的resolve方法开头添加日志,确认方法是否被调用:
\Log::info('Items resolver触发,参数:', $args);
如果日志中没有这条记录,说明请求未到达Resolver,大概率是Schema定义有误。
查看GraphQL Playground文档
在Playground的「Docs」面板中,确认items查询是否显示了你定义的参数。如果没有,说明Schema定义未生效,需检查文件路径或语法。检查路由与中间件
确认GraphQL默认路由/graphql未被自定义中间件拦截,比如CSRF验证(Lighthouse默认已排除,但需确认自定义中间件规则)。
内容的提问来源于stack exchange,提问作者Petro Gromovo

