Làm cách nào để thiết kế các điểm cuối API để đăng đối tượng con và nhận tất cả con của tất cả các bậc cha mẹ?


11

Ví dụ tôi có các thực thể: Khách hàng, Báo cáo. Khách hàng có thể có nhiều Báo cáo và tôi nghĩ rằng điểm cuối cho một quản lý Báo cáo duy nhất nên được lồng vào nhau như sau:

/clients/{client_id}/reports/{report_id}

Đối với tất cả các báo cáo của một khách hàng, dự kiến ​​sẽ có:

/clients/{client_id}/reports

Nhưng làm thế nào để tìm một điểm cuối để có được tất cả các Báo cáo của tất cả các Khách hàng để giữ API nhất quán và được thiết kế tốt.

Cách tiếp cận của tôi:

  1. (Tôi đã thấy nó trong một số google api) sử dụng "-" thay vì nó và phân tích thành "tất cả":

/clients/-/reports

Điều này giữ định dạng điểm cuối giống nhau, nhưng trông hơi bất thường, không thể tìm thấy bất kỳ rfc nào đề xuất theo cách này.

  1. Tạo một điểm cuối riêng biệt cho tất cả các báo cáo:

/reports

Nhưng để nhận được Báo cáo của Khách hàng, nó vẫn:

/clients/{client_id}/reports

  1. Tái cấu trúc điểm cuối để làm cho "máy khách" không phải là cha, mà chỉ là một tham số bộ lọc:

/reports?client={client_id} - báo cáo của một khách hàng

/reports - báo cáo của tất cả khách hàng

Trong trường hợp thêm một điểm cuối mới để đăng báo cáo cho một khách hàng cụ thể, nó có thể trông xấu, bởi vì đó sẽ là một yêu cầu POST với một tham số trong URL.

Có bất kỳ đề xuất ý tưởng khác?


2
Bạn có thể quan tâm câu hỏi
Laiv

Câu trả lời:


3

Nhưng làm thế nào để tìm một điểm cuối để có được tất cả các Báo cáo của tất cả các Khách hàng để giữ API nhất quán và được thiết kế tốt.

Trước bất cứ điều gì khác, hãy nhớ rằng không có quy tắc vàng nào để mô hình hóa các API RESTful. Tất cả chúng ta có là những thực tiễn và quy ước tốt nhất. Điều đó đang được nói, câu trả lời có khả năng là - như thường lệ - chọn câu trả lời phù hợp nhất với yêu cầu của bạn và trong trường hợp này là câu trả lời đúng nhất cho mô hình của bạn.

Vì vậy, kiểm tra ba tùy chọn từ tính biểu cảm.

# 1 Ký hiệu "-"

Đây là một ý tưởng sáng sủa. Nó cho phép chúng ta thể hiện điều kiện tất cả những reportsgì thuộc vềclients . Đó là thu hẹp "truy vấn" thành một tập hợp các báo cáo cụ thể (những báo cáo nằm trong clientsranh giới).

Nó giữ khái niệm phân cấp (thuộc) mọi lúc, vì vậy nếu reportscó thể được tìm thấy ở các địa điểm khác nhau, ký hiệu này tạo ra một vấn đề lớn. Ví dụ:

  • Tất cả các báo cáo thuộc về khách hàng /clients/-/reports
  • Tất cả các báo cáo thuộc về các phòng ban /departments/-/reports
  • Tất cả các báo cáo thuộc về nhân viên /employees/-/reports

Tuy nhiên, để truy xuất tất cả các báo cáo có sẵn trong hệ thống, việc giữ cấu trúc phân cấp không cung cấp bất kỳ lợi thế có giá trị nào so với tùy chọn tiếp theo.

# 2 URI khác nhau

Nếu chúng ta không cần thể hiện ranh giới / bối cảnh / phân cấp tại thời điểm truy xuất tất cả các báo cáo có sẵn , cách tiếp cận này có vẻ hợp lý hơn đối với tôi.

URI mới ( /reports) cũng để ngỏ khả năng quản lý báo cáo . Tuy nhiên, chúng tôi không phải cung cấp cho nó một hỗ trợ RESTful hoàn chỉnh nếu chúng tôi thấy không cần thiết. Ví dụ, bạn đã nêu Make a separate endpoint just for all the reports. Điều đó tốt, bạn chỉ phải thực hiện GETvà có thể một số bộ lọc để truy vấn và đó là nó.

Lưu ý rằng bạn vẫn có thể làm điều này /reports?client={client_id}. Có URI khác nhau cho cùng một tài nguyên là tốt. Một số bài viết tôi đã đọc sẽ gọi đây là sự mạnh mẽ .

# 3 Hoàn nguyên thứ bậc

Tôi có cảm giác rằng phương pháp này không đáp ứng mong đợi của bạn. Thêm vào đó, tôi nghĩ rằng, nó sẽ đưa bạn đến điểm khởi đầu.

Kết luận

Lưu ý rằng # 1 và # 2 không loại trừ lẫn nhau. Chúng tôi có thể thực hiện cả hai. Với tình hình thực tế và theo cơ sở của OP, tôi sẽ chỉ thực hiện # 2.


1: nó tương đương với /clients/-/reportstôi đoán


0

Các mẫu thiết kế API của Google đề xuất sử dụng '-' trong kịch bản này.

GET /clients/-/reports

Nguồn:

https://cloud.google.com/apis/design/design_potypes#list_sub-collections


2
Tôi không đồng ý với Google toàn năng, nhưng tôi nghĩ tôi thích cái gì đó giống như /client/{client_id}/report/{report_id}/clients/report/{report_id}
Robert Harvey

2
@RobertHarvey tại sao không chỉ /reports?
Laiv

@Laiv: Điều đó có nghĩa là tất cả các báo cáo. Làm mới trang của bạn; Tôi đã thực hiện một chỉnh sửa ninja.
Robert Harvey

@RobertHarvey Ý tôi là, tại sao không phải là 2 điểm cuối khác nhau /clients.../reports.
Laiv

1
@Laiv: OK, nhưng điều đó chỉ đặt ra câu hỏi "Tôi nên đặt tham số nào trong thân yêu cầu?"
Robert Harvey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.