[REQUEST] Add batch grouping

Đang mở
#359 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
35/100
Loại issue
Tính năng
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
graphql, javascript
Lĩnh vực
backend-api-design

Hướng nghiên cứu

Bắt đầu từ hàm khởi tạo của DataLoader và xem xét tùy chọn cacheKeyFn hiện có cũng như hành vi của batchLoadFn. Xác định batchGroupFn nên phân chia các khóa như thế nào, cần thực hiện bao nhiêu lần gọi batchLoadFn và làm thế nào để các kết quả vẫn được căn chỉnh với các khóa đầu vào; công việc được coi là hoàn tất khi hành vi nhóm được đề xuất đã được đặc tả và được bao phủ bằng các bài kiểm thử.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

enhancement

What problem are you trying to solve?

Handling different parameters in field resolvers with dataloader is tricky.

Let’s have this GraphQL schema:

type Order {
  orderId: Int
  status: String
}

type User {
  userId: Int
  name: String
  orders(status: String): [Order!]
}

type Query {
  GetUsers(search: String): [User!]
}

schema {
  query: Query
}

Then we have query:

query {
    GetUsers(search: "john") {
        userId
        name
        ordersNew: orders(status: "New") {
            orderId
            status
        }
        ordersCompleted: orders(status: "Completed") {
            orderId
            status
        }
    }
}

Here orders resolver with dataloader:

User: {
    orders: async ({ userId }, { status }) => {
      return await ordersLoader.load({userId: userId, status: status});
    }
  },

Here ordersLoader with batchLoadFn:

const ordersLoader = new DataLoader(
  async (params: { userId: number, status?: string }[]): Promise<Order[][]> => {
...
  }
);

In this batch loader function we need to get orders from a database. If we have all orders stored in one table we can have single query, like:

SELECT * from Orders WHERE userId IN (:userIds) and status IN (:statuses)

Then loop through params and return the result. No real issues, so far.

Now let’s think orders in different statuses can’t be queried with a single query. For example, “New” orders are in “Online” db and “Competed” are moved in some “Archive” db. So, we need to have 2 queries. Then we need to build results properly based on input params. It is doable but even with this simple example not so easy. In real life we may have multiple parameters and we need to handle all permutations of them.

Describe the solution you'd like

I suggest adding a new option to DataLoader constructor. Very similar to existing cacheKeyFn – batchGroupFn?: (key: K) => C;. Based on result of this function batchLoadFn function needs to be called as many times as many different results gives batchGroupFn. I.e. I want to group batches by input keys.

For my example it would be:

batchGroupFn: (key: { userId: number, status?: string }) => (key.status??"")

So for each status it will be separate call of batchLoadFn. It will simplify this function a lot.

Please let me know if this solution is feasible. Or maybe there is alternative/better solution?

Ngôn ngữ chính
JavaScript
Star
13.4k
Fork
522
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của graphql/dataloader

Tất cả issue của graphql/dataloader

Issue tương tự

Thêm issue về JavaScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.