考虑这个例子:
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 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
}
}
另外,最重要的是,它将删除整个字段查询,包括参数。它还会清理可能使用的所有变量(如果其他字段未使用)。
附注还有功能标记的用例