GraphQL使用字段值作为另一个查询的变量

时间:2017-07-21 16:09:32

标签: javascript reactjs graphql apollo

我查询同一组件中需要的2个对象。问题是其中一个查询必须等待另一个查询并使用其id字段作为另一个的参数。不知道如何实现这一点。

const PlayerQuery = gql`query PlayerQuery($trackId: Int!, $duration: Int!, $language: String!) {
  subtitle(trackId: $trackId, duration: $duration) {
    id,
    lines {
      text
      time
    }
  }
  translation(trackId: $trackId, language: $language, subtitleId: ???) {
    lines {
      translation
      original
    }
  }
}`;

因此,在上面的查询中,translation需要subtitleId作为subtitle查询返回的参数。
我在客户端和服务器上都使用了Apollo。

1 个答案:

答案 0 :(得分:7)

这是一个很好的问题,因为它说明了REST / RPC样式API和GraphQL之间的重大差异。在REST样式API中,您返回的对象仅包含有关如何获取更多数据的元数据,并且API使用者应该知道如何在这些表上运行JOIN。在您的示例中,您需要使用ID属性加入subtitletranslation。在GraphQL中,对象很少独立存在,关系编码到模式本身。

您没有发布schema,但从它的外观来看,您创建了一个translation对象和一个subtitle对象,并在根查询中公开了它们。我的猜测是它看起来像这样:

const Translation = new GraphQLObjectType({
  name: "Translation",
  fields: {
    id: { type: GraphQLInt },
    lines: { type: Lines }
  }
});

const SubTitle = new GraphQLObjectType({
  name: "SubTitle",
  fields: {
    lines: { type: Lines }
  }
});

const RootQuery = new GraphQLObjectType({
  name: "RootQuery",
  fields: {
    subtitle: { type: SubTitle },
    translation: { type: Translation }
  }
});

module.exports = new GraphQLSchema({
  query: RootQuery
});

您应该做的是与这样的翻译 INSIDE OF 字幕建立关系。 GraphQL的目标是首先在数据中创建图形或关系,然后找出如何公开该数据的入口点。 GraphQL允许您在图形中选择任意子树。

const Translation = new GraphQLObjectType({
  name: "Translation",
  fields: {
    id: { type: GraphQLInt },
    lines: { type: Lines }
  }
});

const SubTitle = new GraphQLObjectType({
  name: "SubTitle",
  fields: {
    lines: { type: Lines }
    translations: {
      type: Translation,
      resolve: () => {
        // Inside this resolver you should have access to the id you need
        return { /*...*/ }
      }
    }
  }
});

const RootQuery = new GraphQLObjectType({
  name: "RootQuery",
  fields: {
    subtitle: { type: SubTitle }
  }
});

module.exports = new GraphQLSchema({
  query: RootQuery
});

注意:为清楚起见,我遗漏了参数字段和任何其他解析器。我确定你的代码会更复杂,我只想说明一点:)。