最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - GraphQL use field value as variable for another query - Stack Overflow

programmeradmin6浏览0评论

I'm querying for 2 objects which are both needed in the same ponent. The problem is that one of the queries have to wait on the other and use its id field as an argument for the other. Not sure how to implement this.

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
    }
  }
}`;

So in the query above translation needs subtitleId as an argument which is returned by the subtitle query.
I'm using Apollo both on the client and on the server.

I'm querying for 2 objects which are both needed in the same ponent. The problem is that one of the queries have to wait on the other and use its id field as an argument for the other. Not sure how to implement this.

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
    }
  }
}`;

So in the query above translation needs subtitleId as an argument which is returned by the subtitle query.
I'm using Apollo both on the client and on the server.

Share Improve this question edited Jul 21, 2017 at 16:15 Nick Dima asked Jul 21, 2017 at 16:09 Nick DimaNick Dima 1,5952 gold badges18 silver badges37 bronze badges 1
  • I only just started with GraphQL, but from what I understand, that's not possible. If translation was referenced from the subtitle or lines types in the schema, it probably would be possible, because the resolver would receive the subtitle object. – robertklep Commented Jul 21, 2017 at 16:37
Add a ment  | 

1 Answer 1

Reset to default 17

That's a great question because it illustrates a significant difference between REST/RPC style APIs and GraphQL. In REST style APIs the objects that you return only contain metadata about how to fetch more data, and the API consumer is expected to know how to run the JOINs over those tables. In your example, you have a subtitle and a translation that you need to JOIN using the ID property. In GraphQL, objects rarely exists in isolation and the relationships encoded into the schema itself.

You didn't post your schema but from the looks of it, you created a translation object and a subtitle object and exposed them both in your root query. My guess is that it looks something like this:

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
});

What you should do instead, is to make a relationship to translations INSIDE OF subtitle like this. The goal of GraphQL is to first create a graph or relationships in your data, then to figure out how to expose entry points to that data. GraphQL lets you select arbitrary sub-trees in a graph.

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
});

Note: For clarity, I left out the arguments fields and any additional resolvers. I'm sure your code will be a bit more sophisticated, I just wanted to illustrate the point :).

发布评论

评论列表(0)

  1. 暂无评论