Meteor Apollo GraphQL 接口:返回一个对象数组并在另一个解析器中调用解析器

Posted

技术标签:

【中文标题】Meteor Apollo GraphQL 接口:返回一个对象数组并在另一个解析器中调用解析器【英文标题】:Meteor Apollo GraphQL Interfaces: return an array of object and invoking resolver in another resolver 【发布时间】:2019-04-14 03:06:45 【问题描述】:

我在使用 GraphQl interfaces 时遇到了一些问题。以文档中的示例为例:

interface Vehicle 
  maxSpeed: Int


type Airplane implements Vehicle 
  maxSpeed: Int
  wingspan: Int


type Car implements Vehicle 
  maxSpeed: Int
  licensePlate: String


type Query 
  vehicle: Vehicle


const resolvers = 
  Vehicle: 
    __resolveType(obj, context, info)
      if(obj.wingspan)
        return 'Airplane';
      

      if(obj.licensePlate)
        return 'Car';
      

      return null;
    ,
  ,
  Query: 
    vehicle: () =>  
       // Query Airplane and Car an merge in one single array.
    
  ,
;

背景:我为每个接口实现创建了两个不同的DBs:一个用于Car,一个用于Airplane。但是我没有为Vehicle 创建一个DB,因为它只是一个不保留数据的interface。 (我希望这没问题)

第一个问题是如何访问CarAirplaneresolversVehicle resolver中查询他们各自的DBs?所以在Query.vehicle() 中,我只想调用为获取所有汽车定义的解析器以获取所有汽车,并调用用于获取飞机的解析器以获取数据库中的所有飞机。 (注意使用Car.find().fetch()并不总是有效的,因为在查询之前,还需要做很多其他查询也避免代码重复)。

第二个问题是,在示例中,obj.wingspan 假设 obj 应该是一个对象。因此,从Query.vehicle() 返回一个数组将无济于事,因为此查询在Vehicle.__resolveType 中使用。所以从我对 GraphQl 接口的体验来看,它只从查询中返回一个对象。 我的目标是通过以下查询获得:


  vehicle 
    maxSpeed

    ... on Car 
            licensePlate
    
    ... on Airplane 
      wingspan
    
  

以下结果:


  "data": 
    "car": [
      
        "maxSpeed": 200,
        "licensePlate": 1.8
      ,
      
        "maxSpeed": 120,
        "licensePlate": "String"
      ,
      ...
    ],
    "Airplane": [
      
        "maxSpeed": 500,
        "wingspan": "String"
      ,
      
        "maxSpeed": 700,
        "wingspan": 1.5
      ,
      ...
    ]
  

【问题讨论】:

【参考方案1】:

听起来您可能正在尝试返回多个对象。如果是这样,您需要返回一个对象数组:

type Query 
  vehicles: [ Vehicle ]

如果您只是想通过 ID 返回单个对象,请在您的车辆解析器中尝试两个数据库并返回带有结果的数据库:

const resolvers = 
  Query: 
    vehicle: (parent, args) => 
      const  id  = args;

      const [ car, plane ] = await Promise.all(
        await carDB.get(id),
        await planeDB.get(id)
      )

      return car || plane
    
  

编辑

如果你还没有做到这一点:

要得到你所描述的,你需要别的东西:

类型定义

interface Vehicle 
  maxSpeed: Int


type Airplane implements Vehicle 
  maxSpeed: Int
  wingspan: Int


type Car implements Vehicle 
  maxSpeed: Int
  licensePlate: String


type Query 
  vehicles: VehiclesConnection


type VehiclesConnection 
  car: [ Car ]
  airplane: [ Airplane ]

解析器

const resolvers = 
  Query: 
    vehicle: () => 
      const [ cars, planes ] = await Promise.all(
        await carDB.findAll(),
        await planeDB.findAll()
      )

      return  cars, planes 
    
  

查询


  vehicle 
    car 
      maxSpeed
      licensePlate
    
    airplane 
      maxSpeed
      wingspan
    
  

备用查询


  vehicle 
    car 
      ...VehicleFragment
    
    airplane 
      ...VehicleFragment
    
  


fragment VehicleFragment on Vehicle 
  maxSpeed

  ... on Car 
    licensePlate
  
  ... on Airplane 
    wingspan
  

结果


  "data": 
    "car": [
      
        "maxSpeed": 200,
        "licensePlate": 1.8
      ,
      
        "maxSpeed": 120,
        "licensePlate": "String"
      ,
      ...
    ],
    "Airplane": [
      
        "maxSpeed": 500,
        "wingspan": "String"
      ,
      
        "maxSpeed": 700,
        "wingspan": 1.5
      ,
      ...
    ]
  

【讨论】:

感谢您的回答。我已经想通了。我想要实现的是上面显示的结果,每个数据库(汽车、飞机……)分组。

以上是关于Meteor Apollo GraphQL 接口:返回一个对象数组并在另一个解析器中调用解析器的主要内容,如果未能解决你的问题,请参考以下文章

在 apollo (graphql) 查询中无法识别 FlowRouter

带有 Meteor 的 Blaze-Apollo,观察者不会触发变量更改的订阅

如何使用 apollo 客户端从 schema.graphql 中提取 typescript 接口:codegen

Apollo Client 3:如何在客户端为 graphql 接口实现缓存?

用于 C++ 和 .NET 的 GraphQL 客户端

如何从 Apollo Server 端点获得完整的 GraphQL 架构?