如果过滤变量为空,GraphQL 禁用过滤

GraphQL disable filtering if filter variable is empty

我有一个 Gatsby GraphQL 查询,用于查询按日期排序并按类别过滤的帖子列表。

{
  posts: allContentfulPost(
    sort: {fields: [date], order: DESC},
    filter: {category: {slug: {eq: $slug}}}
  ) {
    edges {
      node {
        title {
          title
        }
        date
      }
    }
  }
}

现在当 $slug 是空字符串 "" 时,我得到

{
  "data": {
    "posts": null
  }
}

有没有办法获取所有帖子?

此查询不可能,即使 @skip/@include 指令也无济于事,因为您无法将它们应用于输入字段。

我建议要么调整服务器端逻辑,以便 'eq' 字段中的 null 将忽略此过滤器,要么编辑正在发送的查询(imo 不太有利)。

您使用的 graphql 模式似乎缺少您需要的过滤支持..

您可以使用正则表达式过滤器来发挥您的优势。如果您传递一个空表达式,那么将返回所有帖子,因为所有内容都会匹配。

query Posts($slugRegex: String = "//"){
  posts: allContentfulPost(
    sort: {fields: [date], order: DESC},
    filter: {category: {slug: {eq: $slugRegex}}}
  ) {
    # Rest of the query.
  }
}

默认情况下,将返回所有帖子(如果未传递任何内容,$slugRegex 是一个空的正则表达式)。当 $slugRegex 成为一个有意义的表达式时,只有匹配的帖子才会显示。

至于传递值,我假设您正在使用 gatsby-node.js 创建页面。既然如此,就这么简单:

// gatsby-node.js

exports.createPages = async ({ actions }) => {
  const { createPage } = actions

  // Create a page with only "some-slug" posts.
  createPage({
    // ...
    context: {
      slugRegex: "/some-slug/"
    }
  })

  // Create a page with all posts.
  createPage({
    // ...
    context: {
      // Nothing here. Or at least no `slugRegex`.
    }
  })
}

如果有人需要针对 Gatsby 以外的其他系统的解决方案,可以使用 @skip@include.

来完成
fragment EventSearchResult on EventsConnection {
  edges {
    cursor
    node {
      id
      name
    }
  }
  totalCount
}

query Events($organizationId: UUID!, $isSearch: Boolean!, $search: String!) {
  events(condition: { organizationId: $organizationId }, first: 100)
    @skip(if: $isSearch) {
    ...EventSearchResult
  }
  eventsSearch: events(
    condition: { organizationId: $organizationId }
    filter: { name: { likeInsensitive: $search } }
    first: 100
  ) @include(if: $isSearch) {
    ...EventSearchResult
  }
}

然后在您的客户端代码中,您将向查询提供 search 和 isSearch 并获取您的事件,例如:

const events = data.eventsSearch || data.events