Javascript 正在解析不同解析程序上的联合类型
采取这一方案:Javascript 正在解析不同解析程序上的联合类型,javascript,graphql,apollo-server,Javascript,Graphql,Apollo Server,采取这一方案: union Vehicle = Airplane | Car type Airplane { title: String wingSpan: Int } type Car { title: String wheels: Int } type Person { vehicle: [Vehicle!] } 此查询: person { vehicles { ... on Car {
union Vehicle = Airplane | Car
type Airplane {
title: String
wingSpan: Int
}
type Car {
title: String
wheels: Int
}
type Person {
vehicle: [Vehicle!]
}
此查询:
person {
vehicles {
... on Car {
title
wheels
}
... on Airplane {
title
wingSpan
}
}
}
这些解析器:
// vehicle-resolver.js
export default {
Vehicle: {
__resolveType(obj) {
if (obj.wheels) {
return "Car"
} else {
return "Airplane"
}
}
}
}
// person-resolver.js
export default {
Person: {
vehicles(obj, args, context) {
// Am I resolving a car or an airplane now - or even both?
// I need to ask my CarService with `obj.personId` or my AirplaneService with `obj.personId` also, but I only want to query it if the query is asking for it.
}
}
}
在我的
Person->vehicles(…)
上,我不确定什么时候应该查询我的不同服务以获得汽车和飞机?在该方法中,我不知道我们正在解析哪种类型。您将无法知道您的工会在车辆的分解器中解析为什么类型,因为车辆的\u resolveType
字段实际上取决于它从该分解器接收到的数据
听起来您希望客户机能够请求服务器查询此人的汽车或飞机,或两者,然后让服务器相应地执行操作。这通常通过向字段传递参数来完成,例如:
# type definitions
type Person {
vehicles(type: VehicleType): [Vehicle!]
}
enum VehicleType {
CAR
AIRPLANE
}
//resolver
vehicles(obj, { type }, context) {
if (type === 'CAR') // fetch and return cars
if (type === 'AIRPLANE') // fetch and return planes
// otherwise fetch and return both
}
从客户机的角度来看,将类型标识为参数(type:Car
),然后再标识为条件片段(…on Car
)可能有点多余,但这是最简单的解决方案
或者,您可以选择文档较少的路径,查看客户机在每个请求的基础上实际请求了哪些字段。这可以通过挖掘(信息)来实现。我认为使用阿波罗,您应该能够获取如下字段列表:
info.fieldNodes[0].selectionSet.selections.map(s => s.typeCondition.name.value)
然后,您可以检查请求的类型,并让解析器相应地执行操作
然而采用前一种方法(即在字段中添加类型参数)还有一个额外的好处。作为客户机,如果我想将查询从获取汽车更改为获取飞机,我不想存储两个(或更多)不同的查询,也不想根据尝试获取的类型在它们之间切换
在客户机的上下文中,如果类型是可变的,那么它可能只是应用程序状态中持久化的变量。因此,作为客户机,我更愿意将该变量与查询一起传递。如果我的变量改变,我的查询结果也会改变,但我不必担心改变查询本身(也就是说,它可以包括两种类型的条件片段)。回答得很好!这一次我将使用第一种方法,但是解释得非常好!