如何忽略未知的枚举值?
How to ignore unknown enum values?
我想知道ignore/discard GraphQL/Apollo 服务器中的未知枚举值的最佳方法是什么。
假设我的 GraphQL 模式定义了枚举数组 "enum Service { Supermarket, TicketSales }",它现在工作正常,但后来我使用的其他服务添加了一些新值(例如 Playground),而我的客户端却没有支持它,我只想忽略它,return 支持的值没有错误。
在 GraphQL 中执行此操作的最佳方法是什么。我的第一个想法是制定指令,该指令将从架构中读取支持的值并忽略其他所有内容,但在谷歌搜索后我没有找到任何好的示例如何做到这一点。你能给我指明方向吗?
如果您的解析器函数将接受任意字符串,那么您可以使用自定义标量类型,或者只是 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
}
特别是如果服务器不理解,告诉服务器 "make the type of this object be a playground" 可能没有意义。相反,如果服务器知道 "playground",它可以 return 它以防客户端可能没有预料到。这里有一个枚举可以明确服务器知道什么。服务端说了支持,客户端有责任配合
请注意,客户端有可能查明服务器是否支持游乐场,如果它是一个枚举值,这可能有助于它告知其行为。
query GetServiceTypes {
__type(name: "Service") {
enumValues { name }
}
}
在尝试之后,我发现了一些可以用来解决我原来问题的东西,所以我将 post 放在这里,以防其他人有同样的疑问。
所以我最初的问题简而言之就是我从其他服务收到了几种不同的 "available services" 类型的字符串数组,我想将它们映射到枚举以获得更好的打字稿支持等。但问题是如果我从其他服务获得一些未知值,我的 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% 确定指令是否可以处理此类情况,但至少这是一种可能的解决方案。
我想知道ignore/discard GraphQL/Apollo 服务器中的未知枚举值的最佳方法是什么。
假设我的 GraphQL 模式定义了枚举数组 "enum Service { Supermarket, TicketSales }",它现在工作正常,但后来我使用的其他服务添加了一些新值(例如 Playground),而我的客户端却没有支持它,我只想忽略它,return 支持的值没有错误。
在 GraphQL 中执行此操作的最佳方法是什么。我的第一个想法是制定指令,该指令将从架构中读取支持的值并忽略其他所有内容,但在谷歌搜索后我没有找到任何好的示例如何做到这一点。你能给我指明方向吗?
如果您的解析器函数将接受任意字符串,那么您可以使用自定义标量类型,或者只是 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
}
特别是如果服务器不理解,告诉服务器 "make the type of this object be a playground" 可能没有意义。相反,如果服务器知道 "playground",它可以 return 它以防客户端可能没有预料到。这里有一个枚举可以明确服务器知道什么。服务端说了支持,客户端有责任配合
请注意,客户端有可能查明服务器是否支持游乐场,如果它是一个枚举值,这可能有助于它告知其行为。
query GetServiceTypes {
__type(name: "Service") {
enumValues { name }
}
}
在尝试之后,我发现了一些可以用来解决我原来问题的东西,所以我将 post 放在这里,以防其他人有同样的疑问。
所以我最初的问题简而言之就是我从其他服务收到了几种不同的 "available services" 类型的字符串数组,我想将它们映射到枚举以获得更好的打字稿支持等。但问题是如果我从其他服务获得一些未知值,我的 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% 确定指令是否可以处理此类情况,但至少这是一种可能的解决方案。