2017-11-01 24 views
6

mới để graphQL, tôi Sử dụng sơ đồ sau:Sáp nhập 2 điểm cuối REST để một phản ứng GraphQL đơn

type Item { 
    id: String, 
    valueA: Float, 
    valueB: Float 
    } 

    type Query { 
    items(ids: [String]!): [Item] 
    } 

API của tôi có thể trả về nhiều mặt hàng trên một yêu cầu duy nhất của từng loại (A & B) nhưng không cho cả hai, ví dụ:

REST của Yêu cầu typeA: api/a/items?id=[1,2]
đáp ứng:

[ 
    {"id":1,"value":100}, 
    {"id":2,"value":30} 
] 

REST của Yêu cầu t ypeB: api/b/items?id=[1,2]
đáp ứng:

[ 
    {"id":1,"value":50}, 
    {"id":2,"value":20} 
] 

Tôi muốn kết hợp những 2 điểm cuối api vào một graphQL Phản ứng duy nhất như vậy:

[ 
    { 
    id: "1", 
    valueA: 100, 
    valueB: 50 
    }, 
    { 
    id: "2", 
    valueA: 30, 
    valueB: 20 
    } 
] 

Q: Làm thế nào sẽ một viết một trình phân giải sẽ chạy một số đơn lẻ tìm nạp cho từng loại (nhận được nhiều mục phản hồi) đảm bảo không tìm nạp không cần thiết nào được kích hoạt khi truy vấn là thiếu các loại tức là:

{items(ids:["1","2"]) { 
    id 
    valueA 
}} 

Ví dụ trên chỉ nên lấy api/a/items?id=[1,2] và phản ứng graphQL nên là:

[ 
    { 
    id: "1", 
    valueA: 100 
    }, 
    { 
    id: "2", 
    valueA: 30 
    } 
] 

Trả lời

2

Vì vậy, tôi cho rằng bạn đang sử dụng JavaScript là ngôn ngữ. Những gì bạn cần trong trường hợp này không phải là để sử dụng truy vấn trực tiếp, thay vì sử dụng những mảnh

Vì vậy, các truy vấn sẽ trở thành

{ 
    items(ids:["1","2"]) { 
     ...data 
    }} 

    fragment data on Item { 
     id 
     valueA 
    } 
} 

Tiếp theo trong resolver chúng ta cần phải truy cập vào các mảnh vỡ để tìm các lĩnh vực là một phần của mảnh và sau đó giải quyết dữ liệu dựa trên cùng một. Dưới đây là một tập tin nodejs đơn giản với cùng

const util = require('util'); 

var { graphql, buildSchema } = require('graphql'); 

var schema = buildSchema(` 
    type Item { 
     id: String, 
     valueA: Float, 
     valueB: Float 
    } 

    type Query { 
     items(ids: [String]!): [Item] 
    } 
`); 

var root = { items: (source, args, root) => { 
     var fields = root.fragments.data.selectionSet.selections.map(f => f.name.value); 
     var ids = source["ids"]; 

     var data = ids.map(id => {return {id: id}}); 
     if (fields.indexOf("valueA") != -1) 
     { 
      // Query api/a/items?id=[ids] 
      //append to data; 
      console.log("calling API A") 
      data[0]["valueA"] = 0.12; 
      data[1]["valueA"] = 0.15; 
     } 

     if (fields.indexOf("valueB") != -1) 
     { 
      // Query api/b/items?id=[ids] 
      //append to data; 
      console.log("calling API B") 
      data[0]["valueB"] = 0.10; 
      data[1]["valueB"] = 0.11; 
     } 
     return data 
}, 
}; 

graphql(schema, `{items(ids:["1","2"]) { 
     ...data 
    }} 

    fragment data on Item { 
     id 
     valueA 
    } 

    `, root).then((response) => { 
    console.log(util.inspect(response, {showHidden: false, depth: null})); 
}); 

Nếu chúng ta chạy nó, kết quả là

calling API A 
{ data: 
    { items: [ { id: '1', valueA: 0.12 }, { id: '2', valueA: 0.15 } ] } } 

Nếu chúng ta thay đổi truy vấn để

{ 
    items(ids:["1","2"]) { 
     ...data 
    }} 

    fragment data on Item { 
     id 
     valueA 
     valueB 
    } 
} 

Đầu ra là

calling API A 
calling API B 
{ data: 
    { items: 
     [ { id: '1', valueA: 0.12, valueB: 0.1 }, 
     { id: '2', valueA: 0.15, valueB: 0.11 } ] } } 

Vì vậy, điều này thể hiện cách bạn có thể oid gọi cho api A/B khi các lĩnh vực của họ là không cần thiết. Chính xác như bạn đã yêu cầu

+0

Hoạt động như sự quyến rũ :) –

Các vấn đề liên quan