You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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实现:

  1. 首先在Post模型中定义已发布查询作用域:
// app/Models/Post.php
public function scopePublished($query)
{
    return $query->where('publish', 1);
}
  1. 修改Schema中posts字段,绑定该作用域:
type Query {
    posts: [Post!]! @paginate @scope(name: "published")
}

该方案同样是服务端强制过滤,客户端无法干预过滤逻辑,后续扩展规则只需要修改模型里的Scope方法即可,不需要调整Schema。


内容的提问来源于stack exchange,提问作者devmrh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:15:54