Laravel 9.48+Lighthouse 6.6:如何为@find指令自定义查询添加动态字段?
解决Lighthouse @find指令下添加动态计算字段的问题
你之前尝试给@find指令加resolver参数是行不通的——Lighthouse的@find指令本身并不支持该参数,它会使用内置逻辑直接查询模型实例,所以你的自定义查询类根本不会被触发。下面提供两种可靠的实现方式:
方法一:利用Laravel模型访问器(推荐)
这是最简洁的方式,直接在模型中定义访问器,Lighthouse会自动将这些访问器映射为GraphQL字段。
- 在Article模型中添加访问器
打开app/Models/Article.php,添加以下代码:
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Article extends Model { // ... 其他模型代码 // 生成published_label字段 public function getPublishedLabelAttribute() { return $this->published ? '已发布' : '草稿'; } // 格式化created_at为指定格式 public function getCreatedAtFormattedAttribute() { return $this->created_at->format('Y-m-d H:i:s'); // 如需中文格式可替换为:return $this->created_at->format('Y年m月d日 H时i分'); } }
- 在GraphQL Schema中声明字段
确保你的Article类型定义包含这两个动态字段:
type Article { id: ID! title: String! text: String! text_shortly: String! creator: User! # 假设关联的是User类型 published: Boolean! published_label: String! # 新增动态字段 created_at_formatted: String! # 新增动态字段 created_at: DateTime! }
- 恢复默认@find查询定义
把Query里的article查询改回原生@find即可,无需自定义resolver:
extend type Query { # ... 其他查询 article(id: ID! @eq): Article @find }
查询时Lighthouse会自动调用模型访问器计算字段值,无需额外处理。
方法二:自定义GraphQL字段解析器
如果需要更复杂的逻辑(比如依赖外部服务、多模型关联计算),可以给字段指定自定义解析器。
- 在Schema中给字段添加@field指令
修改Article类型定义:
type Article { # ... 其他字段 published_label: String! @field(resolver: "App\\GraphQL\\Fields\\ArticleFields@resolvePublishedLabel") created_at_formatted: String! @field(resolver: "App\\GraphQL\\Fields\\ArticleFields@resolveCreatedAtFormatted") }
- 创建字段解析器类
生成app/GraphQL/Fields/ArticleFields.php文件:
namespace App\GraphQL\Fields; use App\Models\Article; use GraphQL\Type\Definition\ResolveInfo; use Nuwave\Lighthouse\Support\Contracts\GraphQLContext; class ArticleFields { public function resolvePublishedLabel(Article $root, array $args, GraphQLContext $context, ResolveInfo $info) { // 可在此编写复杂业务逻辑 return $root->published ? '已发布' : '草稿'; } public function resolveCreatedAtFormatted(Article $root, array $args, GraphQLContext $context, ResolveInfo $info) { return $root->created_at->format('Y-m-d H:i:s'); } }
- 恢复默认@find查询定义
和方法一一致,Query中的article查询保持原生@find即可。
验证效果
现在执行你的GraphQL查询,就能正常返回published_label和created_at_formatted字段的值,不会再出现非空字段返回null的错误。
内容的提问来源于stack exchange,提问作者mstdmstd
相关产品推荐
相关产品推荐

