Meteor Apollo GraphQL Interfaces: возвращает массив объектов и вызывает распознаватель в другом преобразователе - PullRequest
0 голосов
/ 11 ноября 2018

У меня проблемы с интерфейсами GraphQl . Давайте возьмем пример в документе:

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.
    }
  },
};

Справочная информация: я создаю 2 разных DBs для каждой реализации интерфейсов: один для Car и один для Airplane. Но я не создал DB для Vehicle, поскольку это просто interface, который не хранит данные в себе. (Надеюсь это нормально)

Первая проблема состоит в том, как получить доступ к Car и Airplane resolvers, чтобы запросить их соответствующие DBs в Vehicle resolver? Поэтому в 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 Ответ

0 голосов
/ 19 ноября 2018

Похоже, вы пытаетесь вернуть несколько объектов. Если это так, вам нужно вернуть массив объектов:

type Query {
  vehicles: [ Vehicle ]
}

Если вы просто пытаетесь вернуть один объект по идентификатору, в вашем распознавателе транспортного средства просто попробуйте обе базы данных и верните одну с результатом:

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
      },
      ...
    ]
  }
}
...