@include 或 @skip 指令应用于后解析器,而不是预解析器。最终到达后端而不是忽略客户端上的属性

问题描述 投票:0回答:1

考虑这个例子:

query myListQuery($someTest: Boolean) {
  id
  price
  taxRate
  expensiveField @skip(if: $someTest)
}

这里将执行graphQL查询;在其服务器解析器中,GQL 操作主体将被转换为适当的 REST 请求,例如

POST
/list
。 REST API 以一组完整实体进行响应,例如:

[
  { id, product, color, size, price, taxRate, expensiveField }, 
  { id, product, color, size, price, taxRate, expensiveField }, 
  { id, product, color, size, price, taxRate, expensiveField }, 
]

心灵,

expensiveField
;它很昂贵,因为它是根据请求在后端运行时计算的。 (尽管它
Math.multiply(price, taxRate)
)。

现在 GQL 服务器收到了来自 REST 的响应,它开始应用一些属性过滤:首先它返回我最初请求的字段(仅 id、price、taxRate),但其次它应用

@skip
的指令(此处,对于
expensiveField
)。过滤发生在后处理中!这很糟糕,IMO。


我尝试微调

POST
/list
端点,它将接受
?fields=
参数。这样我就可以将我从 GraphQL 请求的确切字段列入白名单。简单的。但我最终意识到,Apollo 客户端和 Apollo 服务器无论如何都会将这些属性发送给 REST,即使它们是在
@skip
的指令下。由于指令应用于后处理。

作为解决方法,我现在需要在前端实现自定义逻辑,以删除标有指令的字段。

query myListQuery($someTest: Boolean) {
  id
  price
  taxRate
  -expensiveField @skip(if: $someTest)
  +#expensiveField @skip(if: $someTest)
}

是否有任何库可以与

import gql from 'graphql-tag';
/
gql`` 
配合使用,并且可以在客户端自动为我删除指令?

apollo-client apollo-server preprocessor gql graphql-tag
1个回答
0
投票

在网上搜索了一段时间后,我来到了这个Apollo Link(了解更多关于Links概念)@freshcells/apollo-link-field-keep

这正是我一直在寻找的。我举个例子:

这就是在源代码中编写代码的方式

query myListQuery {
  id
  price
  taxRate
  expensiveField @keep(if: false)
}

最终指令确实会在客户端删除

expensiveField
字段,产生这样的请求正文:

query myListQuery {
  id
  price
  taxRate
}

它也可以与子字段完美配合。

query myQuery {
  post(id: 123) {
    id
    name
    author @keep(if: false) {
      firstName
      lastName
    }
  }
}

将在客户端完全删除

author {}
,导致:

query myQuery {
  post(id: 123) {
    id
    name
  }
}

另外,最重要的是,它将删除整个字段查询,包括参数。它还会清理可能使用的所有变量(如果其他字段未使用)。

附注还有功能标记的用例

© www.soinside.com 2019 - 2024. All rights reserved.