2016-11-06 12 views
7

Giả sử tôi muốn tạo giao diện RESTful và tôi muốn làm việc với foo s dựa trên ID của chúng. Không có gì mới ở đây:Thực hành tốt nhất để trả về đại diện của tài nguyên cũng là một bộ sưu tập

  • GET /api/foo1 trả về đại diện (ví dụ: sử dụng JSON) foo1.
  • DELETE /api/foo1 xóa foo1.

, vv

Bây giờ hãy để tôi nói với bạn rằng một "foo" là một loại bộ sưu tập điều. Vì vậy, tôi muốn có thể để thêm một "thanh" tới "foo":

  • PUT /api/foo1/bar3 thêm bar3 để foo1.
  • GET /api/foo1/bar3 trả về đại diện của foo1.
  • DELETE /api/foo1/bar3 loại bỏ bar3 từ foo1.
  • DELETE /api/foo1 xóa hoàn toàn foo1 hoàn toàn.

Bây giờ câu hỏi vẫn còn: GET /api/foo1 làm gì? Nó có đơn giản là trả lại một biểu diễn của foo1 như tôi đã giả định ban đầu trong câu hỏi này không? Hay nó trả về một danh sách các quán bar? Hoặc nó có trả về một đại diện của foo1 mà cả hai mô tả của foo1 cũng như bao gồm một danh sách tất cả các thanh chứa?

Hoặc nên GET /api/foo1 chỉ đơn thuần là trả lại một đại diện của foo1 như tôi cho rằng ngay từ đầu, và đòi hỏi một yêu cầu PROPFIND để liệt kê các thanh bên foo1 (phương pháp chụp bởi WebDAV)? Nhưng sau đó để nhất quán, tôi sẽ không phải thay đổi tất cả chức năng kiểu danh sách khác của mình thành PROPFIND, trực tiếp mâu thuẫn với tất cả hàng nghìn hướng dẫn RESTful đó có sử dụng GET /api/foo1 để liệt kê nội dung không?

Trả lời

2

Ngữ nghĩa của webdav chưa bao giờ thực sự được đối chiếu với các thành ngữ của giao diện RESTful.

Về lý thuyết, GET nên truy xuất biểu diễn trạng thái của tài nguyên và PROPFIND nên được sử dụng để truy xuất các thành viên của bộ sưu tập.

Vì vậy, bạn nên làm điều này:

  • GET/api/foo1/- trở về trạng thái của foo1 chỉ
  • PROPFIND/api/foo1/- trả về các thành viên của foo1

Hầu hết devs phía trước sẽ freak ra nếu bạn nói với họ để sử dụng PROPFIND, mặc dù nó hoàn toàn được hỗ trợ trong trình duyệt js triển khai.

Cá nhân tôi sử dụng một cổng WebDAV/json, nơi yêu cầu được thực hiện sử dụng thành ngữ RESTful, nhưng chuyển đến thi WebDAV tôi

Ví dụ tôi sẽ làm điều này:

GET /api/foo1/_PROPFIND?fields=name,fooProp1,fooProp2 

Và đó sẽ quay trở lại

[ 
{ name : "bar1", fooProp1: "..", fooProp2 : ".."}, 
{ name : "bar2", fooProp1: "..", fooProp2 : ".."} 
] 

Một lợi thế của phương pháp này là khách hàng có thể kiểm soát các thuộc tính json được trả lại. Điều này là tốt bởi vì một API phong phú sẽ có rất nhiều thuộc tính, nhưng trong hầu hết các trường hợp, khách hàng không cần tất cả chúng.

1

Các tuyến đường và hoạt động của chúng trong API RESTfull được thiết kế hoàn toàn bởi các nhà phát triển. Đó là nhà phát triển, người quyết định những gì cần trả lại khi yêu cầu một tuyến đường cụ thể cho biết, GET /api/foo1.

Và nhà phát triển nên thiết kế mọi tuyến đường bao gồm /api/foo1/bar. Không có quy tắc cụ thể về những gì một tuyến đường cụ thể nên làm. Nếu API của bạn là một dự án mã nguồn mở, hãy tạo một tài liệu rõ ràng và rõ ràng về mọi tuyến đường.

Đừng lãng phí thời gian của bạn suy nghĩ về các chiến lược trường học cũ.

3

Sau khi cân nhắc một số, tôi nghĩ giải thích khái niệm tốt nhất từ ​​quan điểm RESTful thường là "điều" không giống với "bộ sưu tập" của nó. Vì vậy, trong khi trong thế giới WebDAV, directory/ có thể là điều tương tự giữ các tệp của nó, trong thế giới RESTful, tôi có thể có một đường dẫn phụ directory/files/ riêng biệt cho các tệp được chứa. Bằng cách đó tôi có thể thao tác các thư mục riêng biệt với các tập tin giữ.

Hãy xem xét API RESTful cho trang trại chứa kho thóc. Điểm cuối farm/api/barns/ có thể trả về một danh sách các kho, một trong số đó sẽ là farm/api/barns/bigredbarn. Naively tôi sẽ nghĩ rằng lấy farm/api/barns/bigredbarn/ sẽ cung cấp cho tôi một danh sách các loài động vật trong chuồng, đó là những gì nhắc nhở câu hỏi này.

Nhưng thực sự động vật trong chuồng chỉ là một khía cạnh của Big Red Barn. Nó có thể chứa xe và cỏ khô:

  • farm/api/barns/bigredbarn/animals/
  • farm/api/barns/bigredbarn/vehicles/
  • farm/api/barns/bigredbarn/haybales/

Với phương pháp này tiến thoái lưỡng nan tôi phải đối mặt với không phát sinh.

+0

Tôi thích cách tiếp cận của bạn. Trong thực tế, nó là hành vi tương tự mà thực sự phản đối ngôn ngữ định hướng thực hiện cho mảng hoặc danh sách các đối tượng: thuộc tính đối tượng Array: Chiều dài, Kích thước, ReadOnly Mảng phương pháp GetValue - trả về một mục thuộc tính đối tượng liệt kê: Trưởng, hiện tại Phương thức danh sách GetEnumerator - trả về một đối tượng mà lần lượt sẽ trả về các mục –

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