Apollo Server/GraphQL-返回Null的嵌套数组的属性

Apollo Server/GraphQL-返回Null的嵌套数组的属性,graphql,apollo-server,Graphql,Apollo Server,请容忍我,我会尽力解释的。请让我知道,如果需要更多的信息,我正试图保持尽可能简短 我正在使用Apollo服务器和“Apollo datasource rest”插件访问rest API。当试图从嵌套的对象数组中获取属性值时,我会得到每个字段/属性的空响应。此外,当有多个迭代可用时,被查询的数组仅显示一个迭代 讨论中的字段是火箭类型中的“核心”字段,即launch.Rocket.firstStage.cores 我尝试了各种通过“核心”映射的方法(认为这是它想要的),但没有成功 为了简洁起见,我只

请容忍我,我会尽力解释的。请让我知道,如果需要更多的信息,我正试图保持尽可能简短

我正在使用Apollo服务器和“Apollo datasource rest”插件访问rest API。当试图从嵌套的对象数组中获取属性值时,我会得到每个字段/属性的空响应。此外,当有多个迭代可用时,被查询的数组仅显示一个迭代

讨论中的字段是火箭类型中的“核心”字段,即launch.Rocket.firstStage.cores

我尝试了各种通过“核心”映射的方法(认为这是它想要的),但没有成功

为了简洁起见,我只提供了特定问题的代码。查询的所有其他部分都按预期运行

您可以在此处查看我遇到的API响应:

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;
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;
module.exports = {
  Query: {
    singleLaunch: (_, { flightNumber }, { dataSources }) =>
      dataSources.launchAPI.getLaunchById({ launchId: flightNumber }),
  },
};
数据源-launch.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;
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;
module.exports = {
  Query: {
    singleLaunch: (_, { flightNumber }, { dataSources }) =>
      dataSources.launchAPI.getLaunchById({ launchId: flightNumber }),
  },
};
resolvers.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;
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;
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游乐场)

任何关于我在这里做错了什么的建议都将不胜感激。如果需要更多信息,请再次通知我

谢谢大家!

缺少基本url

应该有

等待此消息。获取(this.baseURL+‘launches’


launchReducer
中应该有一个
map
来返回一个数组,比如:

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=>({
用于返回对象[literal]),与
.map(core=>{return{

from response…看起来不应该有
res[0]
,而应该只有
res
-可能api规范已更改-
console.log(res)
?@xadm-从res中删除括号将导致响应未定义。令人沮丧的是,数据打印到控制台,只是在查询时失败。我今天正在研究查询和解析程序,作为可能的原因。据我所知,RESTDataSource会将传递给此的任何内容追加。get()但我确实尝试了你的解决方案,它没有提供任何更改。API中的数据正在成功返回到查询的其他部分。正如我在问题中所述,这只是较大查询的一部分,所有其他数据都正确返回。问题是这个特定的嵌套数组“cores”没有返回任何数据值。但是,我发现如果我在reducer中为数组提供索引,它将返回一个值。但是我无法在reducer中映射,因此我现在正在研究。请尝试
第一阶段:{cores:{
-不使用
[
我过去曾尝试过,这样做会返回:“应该是Iterable,但没有找到一个用于现场核心。核心。”我想这是有道理的,因为“核心”是一个数组。如果我提供核心的任何属性的索引,我确实会得到响应。因此,飞行:launch.rocket.first_stage.Cores[1].flight返回一个值。我开始认为我的解析程序和/或还原程序没有正确编写,无法完成我要完成的任务。我不小心将我的评论放在了编辑摘要中。@xadm是的!我们都在同一条轨道上,您的回答将我推到了起点。我编辑了您的解决方案,因为从地图返回的内容非常简单使用错误。我会将此标记为正确答案。再次感谢您的帮助!