2012-01-11 37 views
6

Giả sử tôi có hai tài nguyên cấp cao nhất FooBar. Bây giờ, Foo cần được liên kết với một số trong số Bar. Trong một lớp Java này có thể trông như thế này:Thiết kế REST API: liên kết tài nguyên

public class Foo { 

    Set<Bar> bars; 
} 

public class Bar { … } 

Tôi muốn hình đại diện XML của Foo một cái gì đó như thế này:

GET /foos/1 

<foo> 
    … 
    <atom:link rel="self" href="/foos/1" /> 
    <atom:link rel="bars" href="/foos/1/bars" /> 
</foo> 

Vì vậy, tôi khá nhiều để lộ tất cả Bargiao đến một Foo làm tài nguyên lồng nhau. Điều đó có nghĩa là tài nguyên Bar có vòng đời cá nhân (tổng hợp thay vì thành phần). Tài nguyên được lồng nhau sau đó có thể tiếp xúc với tất cả các liên kết Bar một cái gì đó như thế này:

GET /foos/1/bars 

<bars> 
    <atom:link rel="bar" href="/foos/1/bars/1" /> 
    <atom:link rel="bar" href="/foos/1/bars/2" /> 
</bars> 

Alteratively tôi có thể inline bộ sưu tập trong <foo> yếu tố trả trước. Tuy nhiên, tôi vẫn bị mắc kẹt với một số câu hỏi: Mặc dù điều này cho phép tôi xóa độc đáo một số Bar từ một số Foo bằng cách kích hoạt yêu cầu DELETE ví dụ: /foos/1/bars/1 nhưng làm thế nào để gán Bar cho Foo sau đó? Giả sử khách hàng sẽ truy cập /bars nhận:

GET /bars 

<bars> 
    <bar> 
    … 
    <atom:link rel="self" href="/bars/4711" /> 
    </bar> 
</bars> 

và quyết định nó muốn gán /bars/1-/foo/1/bars. Tôi đã suy nghĩ về yêu cầu POST đến /foo/1/bars nhưng không chắc chắn về những gì thực sự gửi. Phần tử link trỏ đến tài nguyên Bar như sau?

POST /foos/1/bars 

<atom:link href="/bars/4711" /> 

Điều này có vẻ khá ổn khi khách hàng vẫn không cần phải tạo URL và chúng tôi vẫn đáp ứng ràng buộc REST. Tuy nhiên, có vẻ hơi lạ với POST liên kết đến máy chủ. Có một giải pháp tốt hơn cho kịch bản này?

+1

Tôi sẽ không ngần ngại trong việc đăng liên kết để thiết lập mối quan hệ giữa hai tài nguyên. Một số người tin rằng bạn nên truy xuất tài nguyên và sau đó POST để tự mô tả, nhưng tôi không tin rằng nó là cần thiết. –

+0

Đó là những gì tôi cũng cảm thấy nguyên nhân bạn đang tạo ra sự trò chuyện không cần thiết và b) không thực sự cần toàn bộ repesentation ở phía máy chủ để thực sự tạo liên kết. –

Trả lời

4

Tôi nghĩ về điều này về các tài nguyên được hiểu bởi máy chủ chứ không phải là các biểu diễn XML đáp ứng (ví dụ) một yêu cầu GET. Tôi có các dịch vụ RESTful trả về JSON hoặc XML hoặc các đại diện khác có khả năng.

Vì vậy, tôi đồng ý với đăng hoặc PUTing của bạn để

/foos/{fooId}/bars 

để xác định một trong hai danh sách đầy đủ các thanh hoặc việc bổ sung một số quán bar.

Định dạng của tải trọng đã đăng có thể là bất kỳ dạng tự nhiên được tuần tự hóa nào cho loại phương tiện bạn đang sử dụng. Trong trường hợp của tôi nó thường là một chuỗi JSON và vì vậy trong việc thực hiện dịch vụ của tôi sẽ deserialise và thấy một mảng của resoruce chuỗi URL tham chiếu.

Nếu bạn

<atom:link href="/bars/4711" /> 

cũng deserialise độc ​​đáo sau đó tôi không thấy một vấn đề nếu các hình thức tuần tự là một chút, ừm, trang trí.

Tóm tắt: thực hiện điều tự nhiên cho serialiser (de) của bạn.

+0

Thực ra tôi không nghĩ rằng vấn đề đại diện thực sự ở đây. Câu hỏi rất giống nhau sẽ xuất hiện nếu tôi sử dụng JSON. Tôi chỉ chọn XML làm ví dụ ở đây vì có một phần tử 'link' chuẩn và tôi phải tự mình tạo ra một thứ gì đó trong JSON. Cảm ơn câu trả lời của bạn tuy nhiên! –

+0

cũng đại diện trong trường hợp của bạn có các từ nguyên tử: liên kết, và tôi nghĩ rằng đó là nguyên nhân của mối quan tâm của bạn. Một id duy nhất như "/ bars/4711" có vẻ khá không gây tranh cãi với tôi - bạn phải có một số id, đúng không? – djna

+0

Phải, lý do điều này có thể cảm thấy hơi lạ với tôi là tôi đã gửi liên kết từ máy chủ đến máy khách chỉ cho đến nay để cho phép khách hàng điều hướng tài nguyên. Không bao giờ có sự cần thiết phải POST một liên kết trở lại và bị mắc kẹt bởi cảm giác khách hàng sẽ phải đưa ra các URL và do đó phá vỡ nguyên tắc REST. Nhưng thực ra nó phát hiện ra nó ở phía trước, nên tôi sẽ ổn thôi. –

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