GraphQL отключить фильтрацию, если переменная фильтра пуста
У меня есть запрос Gatsby GraphQL для списка сообщений, упорядоченных по дате и отфильтрованных по категориям.
{
posts: allContentfulPost(
sort: {fields: [date], order: DESC},
filter: {category: {slug: {eq: $slug}}}
) {
edges {
node {
title {
title
}
date
}
}
}
}
Прямо сейчас, когда $slug
пустая строка ""
, Я получил
{
"data": {
"posts": null
}
}
Есть ли способ получить все сообщения вместо этого?
3 ответа
Вы можете использовать фильтр регулярных выражений в своих интересах. Если вы передадите пустое выражение, все сообщения будут возвращены, потому что все будет соответствовать.
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
С этим запросом это невозможно, даже директивы @skip/@include не помогут, потому что вы не можете применить их к полям ввода.
Я бы предложил либо настроить логику на стороне сервера так, чтобы значение null в поле 'eq' игнорировало этот фильтр, либо либо редактировать отправляемый запрос (менее благоприятный imo).
Похоже, что в схеме graphql, с которой вы работаете, отсутствует необходимая поддержка фильтрации..