Khi nào nên sử dụng tài nguyên lồng nhau trong API RESTful


16

Tôi có hai tài nguyên: người dùng và liên kết.

Người dùng có thể có một số liên kết liên kết với họ. Tôi đã thiết kế API RESTful của mình để bạn có thể tiếp cận các liên kết được liên kết với người dùng tại URI sau:

/users/:id/links

Tuy nhiên, tôi luôn cần có một URI cho chỉ các liên kết - đôi khi tôi có thể muốn tất cả các liên kết, bất kể người dùng.

Đối với điều này, tôi có:

/links

Điều này nghe có ổn không? Có hai URI cho các liên kết?

Thay vào đó, tôi tự hỏi liệu tôi có nên truy cập các liên kết cho người dùng có URI không, chẳng hạn như:

/links/user/:id hoặc là /links/?user=:id

Bằng cách này, tôi chỉ có một tài nguyên cho các liên kết.


3
hmm .. Điều này có vẻ thanh lịch hơn:/links/user/:id
theMarceloR

7
@theMarceloR: Đó là ví dụ duy nhất trong số ba ví dụ mà tôi không thấy rõ ràng. Là tài nguyên cho một liên kết hoặc người dùng? URI ít mơ hồ hơn khi sử dụng phương thức tài nguyên lồng nhau ( /users/:id/links) hoặc phương thức chuỗi truy vấn ( /links/?user=:id) vì thực tế nó là một truy vấn. /links/user/:idcó thể trông đẹp và / hoặc dễ dàng hơn để định tuyến trong một số khung nhưng nó thực sự khá khó hiểu.
Aaronaught

Câu trả lời:


16

Không, không có gì sai khi có nhiều tài nguyên cho cùng một "thứ", trong trường hợp này là danh sách các liên kết.

Chúng tôi gần đây đã phải vật lộn với cùng một vấn đề. Quyết định của chúng tôi là có tất cả các tài nguyên khi không có quyền sở hữu nghiêm ngặt không được lồng vào nhau. Nói cách khác, các liên kết sẽ được mô hình hóa theo

/links -- all links
/links/:linkid -- a particular link

Sau đó, các bộ lọc trên bộ sưu tập liên kết được thể hiện dưới dạng tham số truy vấn. Vì vậy, để có được các liên kết của một người dùng nhất định, bạn sẽ sử dụng:

/links?user=/users/:userid

Điều này cũng cho phép cấu tạo bộ lọc dễ dàng hơn:

/links?user=/users/10&since=2013-01-01

Và thật dễ hiểu về mặt khái niệm - bạn có một bộ sưu tập các mặt hàng và bạn thêm các bộ lọc cho nó.

Điều đó đang được nói, không có gì "RESTful" về cách tiếp cận này hơn bất kỳ lược đồ đặt tên URI nào khác. Đó chỉ là một quy ước mà chúng tôi thấy các nhà phát triển có thể đọc và dễ hiểu cho con người. REST không quan tâm đến những gì bạn đặt trong các định danh tài nguyên của bạn.


1
"Tất cả các tài nguyên không có quyền sở hữu nghiêm ngặt không được lồng vào nhau" nghe có vẻ là một quy tắc tốt phải có. Cảm ơn nhiều.
Oliver Joseph Ash

5
Tôi muốn nói rằng có một cái gì đó sai trái với việc có nhiều nguồn lực cho các thực thể vật lý như nhau, nhưng đó không phải là thực sự đây là những gì. Mỗi liên kết riêng lẻ có một URL chính tắc (links /: id), trong khi mỗi tài nguyên ở trên thực tế là một tài nguyên (/ liên kết) với các bộ lọc được áp dụng. Ngoài ra, tôi bị kỳ lạ bởi ?user=users/:useridchuỗi truy vấn; Có chuyện gì với chỉ ?userid=:useridvậy?
Aaronaught

2
@Aaronaught: lý do để gắn bó với uri thay vì id trần là để khách hàng có thể đối xử bình đẳng với tất cả các định danh tài nguyên, đó là một khách hàng chỉ cần biết rằng 'người dùng này được xác định bởi "/*******"; trong đó các *màu đục. nhưng cùng một mã định danh luôn có thể được sử dụng để tham chiếu đến tài nguyên đó (như trong, với các liên kết), để lấy phiên bản mới nhất của tài nguyên đó, v.v. nội dung của uri đó chỉ được hiểu bởi máy chủ gốc. Điều này cũng có nghĩa là nếu số nhận dạng cần thay đổi, giả sử /realm/:businessid/users/:id, máy khách hoàn toàn không thay đổi.
Độc thân Tăng tốc

@TokenMacGuy: Xin lỗi, tôi không hiểu bất kỳ phần nào trong bình luận của bạn. Sự khác biệt thực tế giữa /users/:userid/linksvà là /links?userid=:useridgì? Trong cả hai trường hợp, số nhận dạng không thay đổi, họ lấy phiên bản hiện tại của tài nguyên đó và khách hàng đối xử với họ theo cùng một cách. Không có thứ gọi là URL chuẩn cho việc này vì đây không phải là tài nguyên, đó là truy vấn, vì vậy đây chỉ là hai loại cú pháp truy vấn khác nhau. Tôi cũng không rõ khách hàng sẽ không cần thay đổi như thế nào nếu cấu trúc URL thay đổi; đó được coi là một sự thay đổi đột phá trong REST trừ khi có 301.
Aaronaught

1
@Aaronaught: Tôi có thể đã hiểu nhầm mối quan tâm của bạn. Giả sử /linkshỗ trợ giao diện truy vấn, /links?user=/users/123cho phép cách tiếp cận hộp đen đối với các định danh tài nguyên trong các máy khách /links?userid=123không. cái sau đòi hỏi khách hàng hiểu được userid là gì và làm thế nào để có được nó, có lẽ là từ tài nguyên mà nó thu được từ /users/123hoặc /links/456/user. Cái trước có nghĩa là khách hàng có thể sử dụng uri không thay đổi; giả sử /links/.../userđưa ra một phản ứng hypermedia (giả sử, với Location:các tiêu đề).
Độc thân Tăng tốc

1

Vì vậy, mối quan tâm của tôi là: / users /: userid / links trả về "links", NHƯNG nếu user_id không được xác định, điều này sẽ trả về 404.

Tuy nhiên

/ links? userid =: userid có khả năng trả về một danh sách trống (về cơ bản là 200) mà thực sự có thể là một lỗi. Và hoàn toàn có thể.

Mặc dù cả hai đều hoạt động, việc lồng nhau cung cấp cho bạn chức năng bổ sung mà sau này bạn có thể rút ra.

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.