从两个GraphQL解析器返回一个结果

时间:2018-09-21 17:56:17

标签: javascript graphql apollo graphql-js apollo-server

我正在为我的GraphQL模式将两个查询的结果合并为一个。我有一个stockprice类型,每个类型都可以单独解析,但是我不知道如何合并结果。 这是我的typedefs和解析器`:

const typeDefs = gql`
    type Query{
        stock(symbol: String!): Stock
        price(symbol: String!): Price
    }

    type Stock {
        companyName: String
        exchange: String
        industry: String
        sector: String
        tags: [String]
        cost: Price
    }

    type Price {
        cost: String
    }

`;

const resolvers = {
    Query:{
        stock: async(root, {symbol}, {dataSources}) =>{
            return dataSources.myapi.getSomeData(symbol)
        },
        // dont have a name for your property? ADD ONE!
        price: async(root, {symbol}, {dataSources})=>{
            return {'cost': dataSources.myapi.getAPrice(symbol)}
        }
    }
};

如果我这样运行查询,则会得到null的股票价格:

query{
  stock(symbol:"aapl"){
    tags
    cost{
      cost
    }
  }
}

结果如下:

{
  "data": {
    "stock": {
      "tags": [
        "Technology",
        "Consumer Electronics",
        "Computer Hardware"
      ],
      "cost": null
    }
  }
}

但是,如果我查询价格,则会得到价格的预期结果:

query{
  price(symbol:"aapl"){
      cost
  }
}

我正在使用datasources,文件看起来像这样:

class MyApi extends RESTDataSource{
    constructor(){
        super();
        this.baseURL = 'https://api.iextrading.com/1.0';
    }

    async getAPrice(symbol){
        return this.get(`/stock/${symbol}/price`);
    }

    async getSomeData(symbol){
        return this.get(`/stock/${symbol}/company`)
    }
}

module.exports = MyApi;

我想知道为什么会这样。是否存在我做得不好的事情,或者GraphQL在某种程度上缺乏对解析器的理解?

是否建议通过承诺在解析器中返回两个查询?我不确定从这里去哪里。

2 个答案:

答案 0 :(得分:0)

我相信您所拥有的将对解析器进行以下调整:

const resolvers = {
    Query: {
        stock: async(root, {symbol}, {dataSources}) => {
            const stock = await dataSources.myapi.getSomeData(symbol)
            return {...stock, symbol: symbol}
        },
        // dont have a name for your property? ADD ONE!
        price: async(root, {symbol}, {dataSources}) => {
            const cost = await dataSources.myapi.getAPrice(symbol)
            return {cost: cost}
        }
    },
    Stock: {
      cost: async (stockWithSymbol, args, {dataSources}) => {
        const cost = await dataSources.myapi.getAPrice(stockWithSymbol.symbol)
        return {cost: cost}
      }
    }
};

底部的Stock块告诉GraphQL如何解析cost类型的Stock字段。请注意,在根库存查询解析器中,我还将响应扩展为带符号,以便在成本字段解析器的第一个参数中可用。给定股票信息,您也许有更好的价格加载方式,但是只需按照所示的模式进行即可。

答案 1 :(得分:0)

我对此进行了进一步研究,在GraphQL术语中,您所谓的“底部库存块”称为nested resolver。这是我为其他解析器想到的:

Stock:{
    price: async(company, args, {dataSources})=>{
        return {'cost': dataSources.myapi.getAPrice(company.symbol)}
    }
}

这似乎是同一回事吗?