javascript - 在不同解析器上解析联合类型

标签 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 {
            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.
        }
    }
}

在我的人 -> 车辆(...)上,我不确定何时应该查询不同的服务来获取汽车和飞机?在该方法中,我不知道我们正在解析哪种类型。

最佳答案

您将无法知道您的 Union 在解析器内解析 vehicles 的类型。因为__resolveType字段 Vehicle实际上取决于它从解析器接收的数据。

听起来您希望客户端能够请求服务器查询此人的汽车或他/她的飞机或两者,然后让服务器采取相应的操作。这通常通过向字段传递参数来完成,例如:

# 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
}

从客户端的 Angular 来看,必须将类型标识为参数 ( type: Car ),然后在条件片段中再次标识类型 ( ... on Car ) 可能有点多余,但这是最简单的解决方案。

或者,您可以采用记录较少的路径,查看客户端在每个请求的基础上实际请求了哪些字段。这可以通过深入研究 fourth argument passed to the resolver function 来完成。 (信息)。我认为使用 Apollo,您应该能够获取如下字段的列表:

info.fieldNodes[0].selectionSet.selections.map(s => s.typeCondition.name.value)

然后您可以检查所请求的类型并让您的解析器采取相应的行动。

但是,采用前一种方式(即向字段添加类型参数)还有一个额外的好处。作为客户,如果我想将查询从获取汽车更改为获取飞机,我不想存储两个(或更多)不同的查询,并且必须根据我想要获取的类型在它们之间切换.

在客户端的上下文中,如果类型是可变的,它可能只是在应用程序状态中保留的变量。那么,作为客户,我宁愿只将该变量与我的查询一起传递。如果我的变量发生变化,我的查询结果也会发生变化,但我不必担心更改查询本身(即它可以包含两种类型的条件片段)。

关于javascript - 在不同解析器上解析联合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46312796/

相关文章:

amazon-web-services - 如何在 appsync 和 amplify 项目中使用 schema.graphql 而不是 schema.json?

node.js - GET 查询缺失 : Implementing GraphQL Using Apollo On an Express Server

javascript - 如何创建基本客户端以通过 websockets 使用 GraphQL 订阅

graphql - Apollo GraphQL 中的命令式是什么意思?

javascript - $(window).blur() 在智能手机浏览器中无法正常工作?

javascript - 如何绕过 WSO2 IS 登录页面?

javascript - String is incompatible with number (Flow typing optional property with default)

node.js - 登录 apollo-server 的推荐方式

rest - 如何使用apollo客户端发出休息后请求?

javascript - 通过 alpha channel 的图像贴图