我想知道什么是在GraphQL / Apollo服务器中忽略/丢弃未知枚举值的最佳方法。
比方说,我的GraphQL模式定义了枚举数组“枚举服务{超市,TicketSales}”,现在可以正常使用,但是后来我正在使用的其他服务上添加了一些新值(例如Playground),而我的客户却没有不支持它,我只想忽略它并返回支持的值而不会出现错误。
在GraphQL中执行此操作的最佳方法是什么。我的第一个想法是制作一条指令,该指令将从架构中读取受支持的值,而忽略其他所有内容,但是在谷歌搜索之后,我找不到如何执行此操作的任何示例。你能指出我要去哪里吗?
答案 0 :(得分:1)
如果您的解析器函数将接受任意字符串,则可以使用自定义标量类型,也可以仅使用String
。
"""
The type of a service. `Supermarket` means..., and
`TicketSales` means...; any other value is ignored.
"""
scalar Service
GraphQL通常将责任放在客户端上,以符合服务器的期望,而不是让服务器尝试支持任何请求。您可以合理地希望在几个地方出现这样的枚举值:
enum Service { Supermarket, TicketSales }
type Query {
inAReturnValue: Service!
asAQueryParam(service: Service!): Node
}
type Mutation {
asAMutationInput(service: Service!): Node
}
特别是,如果服务器不理解,则告诉服务器“使该对象的类型成为游乐场”可能没有意义。相反,如果服务器知道“游乐场”,则在客户端不期望的情况下可以将其返回。在这里有了枚举可以使服务器明确知道什么。服务器说了支持什么,合作是客户的责任。
请注意,客户端可能会发现服务器是否支持游乐场,是否为枚举值,这可能有助于告知其行为。
query GetServiceTypes {
__type(name: "Service") {
enumValues { name }
}
}
答案 1 :(得分:0)
玩转之后,我发现可以用来解决原始问题的东西,所以我会在这里张贴,以防其他人想知道同一件事。
所以我最初的问题很简短,就是我从另一个服务接收到几种不同的“可用服务”类型的字符串数组,并且我正考虑将它们映射到枚举以获得更好的打字稿支持等。但是问题是,如果我从另一个服务获取一些未知值,我的graphql将失败。
所以我最初的想法是用我最终可以使用的指令来修复它:
# In schema
directive @mapUnknownTo(value: String) on ENUM
enum SomeAttribute @mapUnknownTo(value: "__UNKNOWN__") {
SomeAttribute1
AnotherAttribute
SomethingElse
__UNKNOWN__
}
指令的实现是:
import { SchemaDirectiveVisitor } from 'graphql-tools';
import { GraphQLEnumType } from 'graphql';
export class MapUnknownToDirective extends SchemaDirectiveVisitor {
visitEnum(type: GraphQLEnumType) {
const { value = '__UNKNOWN__' } = this.args;
const valueMap = type.getValues().reduce((map, v) => map.set(v.value, v.name), new Map<string, string>());
type.serialize = (v: string): string => valueMap.get(v) || value;
}
}
因此,这会将所有未在架构中定义的值映射到某个自定义值,这并不是我最初想要的,但是至少它没有给出错误,所以还可以。
我仍然不确定100%是否可以使用指令处理此类情况,但至少这是一种可能的解决方案。