Apollo Client处理gql查询lte/gte空值问题求助
解决方案:处理GraphQL查询中null日期筛选变量的问题
针对你遇到的Apollo Client传入null日期变量导致筛选错误的问题,以下是三种可行的解决方案,覆盖不同场景需求:
方法1:使用GraphQL @include 指令动态包含筛选条件
利用GraphQL的@include指令,仅当变量不为null时才将对应筛选条件加入查询。这种方式简洁直观,多数现代GraphQL服务(包括The Graph子图)都支持该指令。
查询示例:
query GET_DOMAINS($min_date: DateTime, $max_date: DateTime) { domains( where: { AND: [ { expires: { gte: $min_date } } @include(if: $min_date) { expires: { lte: $max_date } } @include(if: $max_date) ] } ) { id expires # 其他需要的字段 } }
原理:
当$min_date为null时,@include(if: $min_date)会跳过该筛选条件;同理$max_date为null时,对应的lte筛选也会被忽略。无论单个或两个变量为null,都能自动适配查询逻辑。
方法2:前端动态构建筛选条件变量
在发起查询前,根据变量是否为null手动组装where条件,只保留非null的筛选规则,避免将null传入GraphQL服务。
代码示例:
// 1. 定义支持动态where的GraphQL查询 const GET_DOMAINS = gql` query GET_DOMAINS($where: Domain_filter) { domains(where: $where) { id expires } } `; // 2. 构建筛选条件的工具函数 const buildDomainFilters = (minDate, maxDate) => { const filters = {}; if (minDate) { filters.expires = { ...filters.expires, gte: minDate }; } if (maxDate) { filters.expires = { ...filters.expires, lte: maxDate }; } return filters; }; // 3. 在组件中使用 const YourComponent = () => { const [minDate, setMinDate] = useState(null); const [maxDate, setMaxDate] = useState(null); const where = buildDomainFilters(minDate, maxDate); const { data } = useQuery(GET_DOMAINS, { variables: { where } }); // 其他组件逻辑... };
原理:
通过工具函数过滤掉null值,仅将存在的日期条件加入expires筛选规则。如果两个日期都为null,where会是空对象,查询将返回所有域名数据。
方法3:用Apollo Link拦截并清理null变量
如果不想修改现有查询或组件逻辑,可以通过自定义Apollo Link在请求发送前自动移除包含null值的筛选条件,对业务代码无侵入。
代码示例:
import { ApolloLink, from } from '@apollo/client'; import { HttpLink } from '@apollo/client/link/http'; import { InMemoryCache } from '@apollo/client/cache'; // 自定义Link:清理where条件中的null值 const filterNullFiltersLink = new ApolloLink((operation, forward) => { const { variables } = operation; if (variables?.where?.expires) { // 过滤掉expires中值为null的筛选规则 const validExpiresFilters = Object.fromEntries( Object.entries(variables.where.expires).filter(([_, value]) => value !== null) ); // 如果过滤后expires无有效规则,直接删除该字段 if (Object.keys(validExpiresFilters).length === 0) { delete variables.where.expires; } else { variables.where.expires = validExpiresFilters; } } return forward(operation); }); // 初始化Apollo Client时加入该Link const client = new ApolloClient({ link: from([ filterNullFiltersLink, new HttpLink({ uri: '你的GraphQL子图地址' }) ]), cache: new InMemoryCache(), });
原理:
该Link会在请求发送到服务端前拦截并修改变量,自动移除expires中值为null的筛选项,确保传入服务端的都是有效的筛选条件。
内容的提问来源于stack exchange,提问作者Kavindu Madushanka
相关产品推荐
相关产品推荐

