【问题标题】:Meteor Apollo GraphQL Interfaces: return an array of object and invoking resolver in another resolverMeteor Apollo GraphQL 接口:返回一个对象数组并在另一个解析器中调用解析器
【发布时间】: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
      },
      ...
    ]
  }
}

【问题讨论】:

    标签: meteor graphql apollo apollo-client apollo-server


    【解决方案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
          },
          ...
        ]
      }
    }
    

    【讨论】:

    • 感谢您的回答。我已经想通了。我想要实现的是上面显示的结果,每个数据库(汽车、飞机……)分组。
    猜你喜欢
    • 2021-03-20
    • 2020-08-02
    • 2023-03-13
    • 1970-01-01
    • 2021-02-26
    • 2018-05-13
    • 1970-01-01
    • 2018-08-27
    • 2021-03-28
    相关资源
    最近更新 更多