Laravel GraphQL如何设置posts查询默认仅返回已发布文章
服务端默认过滤已发布文章实现方法
需求背景
需要让GraphQL的posts分页查询默认仅返回publish=1的已发布文章,过滤逻辑完全在服务端控制,不支持客户端传参修改,无需客户端额外传递过滤参数。
不接受的客户端可控过滤写法如下:
posts(@where(operator: "=", "publish", "1")): [Post!]! @paginate
现有代码参考
客户端调用代码
$: posts = queryStore({ client: getContextClient(), query: gql` query ($first: Int!, $page: Int!) { posts(first: $first, page: $page) { data { id title image excerpt slug view like is_bookmarked is_liked author postCategories { id title } } paginatorInfo { total currentPage lastPage perPage hasMorePages } } } `, variables: { first, page }, requestPolicy: 'cache-and-network', })
原服务端Schema定义
type Query { posts: [Post!]! @paginate } type PostComment{ id: ID! post_id: ID! user_id: ID author: String comment: String! like: Int! dislike: Int! report_count: Int! publish: Boolean! is_liked: Boolean is_bookmarked: Boolean post: Post! @belongsTo created_at: String updated_at: String } type Post { id: ID! title: String! slug: String! view: Int! like: Int! body: String! image: String excerpt: String author: String publish: Boolean! highlight: Boolean! is_liked: Boolean created_at: String is_bookmarked: Boolean postCategories: [PostCategory!]! @belongsToMany postComments: [PostComment!]! @hasMany }
实现方案
基于你使用的Laravel Lighthouse GraphQL框架,有两种无侵入实现方式,都不需要修改现有客户端代码:
方案1:硬编码@where固定值(零PHP代码,适合简单场景)
直接修改Query下的posts字段定义,给@where指令传入服务端固定的value参数,该过滤逻辑不会暴露给客户端,也无法被客户端传参覆盖:
type Query { posts: [Post!]! @paginate @where(operator: "=", column: "publish", value: 1) }
修改后所有对posts的查询会自动追加where publish = 1的SQL条件,分页计数也会自动基于过滤后的结果计算,完全兼容你现有的first/page分页参数。
方案2:绑定模型查询作用域(适合复杂过滤场景)
如果后续需要扩展更多默认过滤规则(比如追加过滤已审核、未删除等条件),可以使用模型Scope实现:
- 首先在
Post模型中定义已发布查询作用域:
// app/Models/Post.php public function scopePublished($query) { return $query->where('publish', 1); }
- 修改Schema中
posts字段,绑定该作用域:
type Query { posts: [Post!]! @paginate @scope(name: "published") }
该方案同样是服务端强制过滤,客户端无法干预过滤逻辑,后续扩展规则只需要修改模型里的Scope方法即可,不需要调整Schema。
内容的提问来源于stack exchange,提问作者devmrh
相关产品推荐
相关产品推荐

