Apollo Server / GraphQL - Свойства вложенного массива, возвращающего нуль

Потерпи меня, я объясню это как можно лучше. Пожалуйста, дайте мне знать, если потребуется дополнительная информация, я стараюсь сделать ее как можно короче.

Я использую Apollo Server и плагин apollo-datasource-rest для доступа к REST API. При попытке получить значения свойств из вложенного массива объектов я получаю нулевой ответ для каждого поля / свойства. Кроме того, запрашиваемый массив показывает только одну итерацию, если доступно несколько.

Рассматриваемое поле - это поле cores внутри типа Rocket, то есть launch.rocket.firstStage.cores.

Я пробовал различные способы сопоставления «ядер» (думая, что это было то, что он хотел), но безуспешно.

Для простоты и краткости я включаю только код конкретной проблемы. Все остальные части запроса работают должным образом.

Вы можете просмотреть ответ API, который я нажимаю здесь: https://api.spacexdata.com/v3/launches/77

schema.js

const { gql } = require('apollo-server');

const typeDefs = gql`
  type Query {
    singleLaunch(flightNumber: Int!): Launch
  }

  type Launch {
    flightNumber: Int!
    rocket: Rocket
  }

  type Rocket {
    firstStage: Cores
  }

  type Cores {
    cores: [CoreFields]
  }

  type CoreFields {
    flight: Int
    gridfins: Boolean
    legs: Boolean
    reused: Boolean
    landingType: String
    landingVehicle: String
    landingSuccess: Boolean
  }
`;

module.exports = typeDefs;

Источник данных - launch.js

const { RESTDataSource } = require('apollo-datasource-rest');

class LaunchAPI extends RESTDataSource {
  constructor() {
    super();
    this.baseURL = 'https://api.spacexdata.com/v3/';
  }

  async getLaunchById({ launchId }) {
    const res = await this.get('launches', {
      flight_number: launchId,
    });
    return this.launchReducer(res[0]);
  }

launchReducer(launch) {
    return {
      flightNumber: launch.flight_number || 0,
      rocket: {
        firstStage: {
          cores: [
            {
              flight: launch.rocket.first_stage.cores.flight,
              gridfins: launch.rocket.first_stage.cores.gridfins,
              legs: launch.rocket.first_stage.cores.legs,
              landingType: launch.rocket.first_stage.cores.landing_type,
              landingVehicle: launch.rocket.first_stage.cores.landing_vehicle,
              landingSuccess: launch.rocket.first_stage.cores.landing_success,
            },
          ],
        },
    };
  }
}

module.exports = LaunchAPI;

resolvers.js

module.exports = {
  Query: {
    singleLaunch: (_, { flightNumber }, { dataSources }) =>
      dataSources.launchAPI.getLaunchById({ launchId: flightNumber }),
  },
};

Запрос

query GetLaunchById($flightNumber: Int!) {
  singleLaunch(flightNumber: $flightNumber) {
    flightNumber
    rocket {
      firstStage {
        cores {
          flight
          gridfins
          legs
          reused
          landingType
          landingVehicle
          landingSuccess
        }
      }
    }
  }
}

Ожидаемый результат

{
  "data": {
    "singleLaunch": {
      "flightNumber": 77,
      "rocket": {
        "firstStage": {
          "cores": [
            {
              "flight": 1,
              "gridfins": true,
              "legs": true,
              "reused": true,
              "landingType": "ASDS",
              "landingVehicle": "OCISLY",
              "landSuccess": true,
            },
            {
              "flight": 1,
              "gridfins": true,
              "legs": true,
              "reused": false,
              "landingType": "RTLS",
              "landingVehicle": "LZ-1",
              "landSuccess": true
            },
            {
              "flight": 1,
              "gridfins": true,
              "legs": true,
              "reused": false,
              "landingType": "RTLS",
              "landingVehicle": "LZ-2",
              "landSuccess": true
            },
          ]
        }
      },
    }
  }
}

Фактический результат (через GraphQL Playground)

{
  "data": {
    "singleLaunch": {
      "flightNumber": 77,
      "rocket": {
        "firstStage": {
          "cores": [
            {
              "flight": null,
              "gridfins": null,
              "legs": null,
              "reused": null,
              "landingType": null,
              "landingVehicle": null,
              "landingSuccess": null
            }
          ]
        }
      },
    }
  }
}

Будем очень признательны за любые предложения относительно того, что я делаю неправильно. Опять же, дайте мне знать, если потребуется дополнительная информация.

Спасибо!


person QMC    schedule 03.05.2019    source источник
comment
из ответа ... похоже, не должно быть res[0], а только res - может быть, спецификации API изменились - console.log(res)?   -  person xadm    schedule 04.05.2019
comment
@xadm - удаление скобок из res приведет к тому, что ответ будет неопределенным. Раздражает то, что данные, выводимые на консоль, просто не выполняются при запросе. Сегодня я рассматриваю запрос и преобразователь как возможную причину.   -  person QMC    schedule 06.05.2019


Ответы (1)


Отсутствует базовый URL

Должно быть

ждать this.get (this.baseURL + 'запускает'


IMHO должен быть map, используемый в launchReducer для возврата массива, например:

launchReducer(launch) {
    return {
      flightNumber: launch.flight_number || 0,
      rocket: {
        firstStage: {
          cores: launch.rocket.first_stage.cores.map(core => ({
            flight: core.flight,
            gridfins: core.gridfins,
            legs: core.legs,
            landingType: core.landing_type,
            landingVehicle: core.landing_vehicle,
            landSuccess: core.land_success,
          })),
        },
      },
    };
}  

.map(core => ({ предназначен для возврата объекта [литерал], то же самое, что и / более короткая версия .map(core => { return {

person xadm    schedule 06.05.2019
comment
Насколько мне известно, RESTDataSource добавляет все, что было передано в this.get (), к BaseURL для меня. Но я все равно попробовал ваше решение, и оно не дало никаких изменений. Данные из API успешно возвращаются в другие части запроса. Как я уже сказал в своем вопросе, это только 1 часть более крупного запроса, все остальные данные которого возвращаются правильно. Проблема в том, что этот конкретный вложенный массив cores не возвращает никаких значений. Однако я обнаружил, что если я предоставлю индекс для массива в редукторе, он вернет значение. Но я не могу отобразить в редукторе, поэтому я сейчас занимаюсь этим. - person QMC; 06.05.2019
comment
попробуйте firstStage: { cores: { - без [ - person xadm; 07.05.2019
comment
Я пробовал это в прошлом, и это возвращает: Expected Iterable, но не нашел для поля Cores.cores. Я полагаю, что это имеет смысл, поскольку «ядра» - это массив. - person QMC; 07.05.2019
comment
Если я предоставлю индекс для любого из свойств ядер, я ПОЛУЧИТЕ ответ. Итак, flight: launch.rocket.first_stage.cores [1] .flight возвращает значение. Я начинаю думать, что мой преобразователь и / или редуктор написан неправильно для того, что я пытаюсь выполнить. - person QMC; 07.05.2019
comment
Я случайно поместил свой комментарий в сводку редактирования. @xadm ДА! Мы оба были на одном пути, и ваш ответ подтолкнул меня к финишу. Я немного отредактировал ваше решение, так как возврат с карты вызывал ошибку. Отмечу это как правильный ответ. Еще раз спасибо за вашу помощь! - person QMC; 07.05.2019