Vì LastUser
và LastUpdate
không thể sửa đổi được bởi khách hàng, tôi sẽ xóa chúng khỏi đại diện cho tài nguyên của bạn hoàn toàn. Hãy để tôi giải thích lý do của tôi với một ví dụ.
Hãy nói rằng chúng tôi ví dụ điển hình API sẽ trở lại với đại diện sau đây cho khách hàng khi được yêu cầu cung cấp một nguồn duy nhất:
GET /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>ipsum</lorem>
<dolor>sit amet</dolor>
<lastUser uri="/user/321">321</lastUser>
<lastUpdate>2011-04-16 20:00:00 GMT</lastUpdate>
</example>
Nếu một khách hàng muốn sửa đổi các nguồn lực, nó sẽ lẽ lấy toàn bộ đại diện và gửi lại cho API.
PUT /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
<lastUser>322</lastUser>
<lastUpdate>2011-04-16 20:46:15 GMT+2</lastUpdate>
</example>
Kể từ khi API tạo ra giá trị cho lastUser
và lastUpdate
tự động và không thể chấp nhận dữ liệu được cung cấp bởi khách hàng, phản ứng thích hợp nhất sẽ là 400 Bad Request
hoặc 403 Forbidden
(kể từ khi khách hàng không có thể thay đổi các giá trị).
Nếu chúng tôi muốn tuân thủ REST và gửi một đại diện đầy đủ của tài nguyên khi thực hiện yêu cầu PUT, chúng tôi cần xóa lastUser
và lastUpdate
khỏi phần trình bày tài nguyên. Điều này sẽ cho phép khách hàng để gửi các thực thể đầy đủ qua PUT:
PUT /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
Các máy chủ sẽ chấp nhận một đại diện đầy đủ bây giờ mà nó không chứa lastUpdate
và lastUser
.
Câu hỏi còn lại là cách cung cấp cho khách hàng quyền truy cập vào lastUpdate
và lastUser
. Nếu họ không cần nó (và các lĩnh vực này được yêu cầu trong nội bộ của API), chúng tôi là tốt và giải pháp của chúng tôi là hoàn toàn yên tĩnh.Tuy nhiên, nếu khách hàng cần truy cập vào dữ liệu này, các phương pháp sạch sẽ sử dụng tiêu đề HTTP:
GET /example/123
...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
X-Last-User: /user/322
...
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
Sử dụng một tiêu đề HTTP tùy chỉnh không phải là lý tưởng vì đại lý người dùng cần phải được dạy về cách đọc nó. Nếu chúng tôi muốn cung cấp cho khách hàng quyền truy cập vào cùng một dữ liệu theo cách dễ dàng hơn, điều duy nhất chúng tôi có thể làm là đưa dữ liệu vào biểu diễn và chúng tôi đang đối mặt với cùng một vấn đề như trong câu hỏi ban đầu của bạn. Tôi ít nhất sẽ cố gắng giảm thiểu nó bằng cách nào đó. Nếu kiểu nội dung được sử dụng bởi các API là XML, chúng ta có thể đưa dữ liệu vào thuộc tính nút thay vì phơi bày chúng trực tiếp như các giá trị nút, ví dụ:
GET /example/123
...
Last-Modified: Sat, 16 Apr 2011 18:46:15 GMT
...
<?xml version="1.0" encoding="UTF-8" ?>
<example last-update="2011-04-16 18:46:15 GMT" last-user="/user/322">
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
</example>
Bằng cách này chúng ta sẽ ít nhất là tránh những vấn đề mà một khách hàng sẽ cố gắng gửi tất cả các nút XML trong một yêu cầu PUT tiếp theo. Điều này sẽ không làm việc với JSON, và giải pháp vẫn còn một chút trên cạnh của idempotency (vì API sẽ vẫn phải bỏ qua các thuộc tính XML khi xử lý yêu cầu).
Thậm chí tốt hơn, như Jonah chỉ ra trong các nhận xét, nếu khách hàng cần truy cập vào lastUser
và lastUpdate
, chúng có thể được hiển thị dưới dạng tài nguyên mới, được liên kết từ tài nguyên gốc, ví dụ: như sau:
GET /example/123
<?xml version="1.0" encoding="UTF-8" ?>
<example>
<id>123</id>
<lorem>foobar</lorem>
<dolor>foobaz</dolor>
<lastUpdateUri>/example/123/last-update</lastUpdateUri>
</example>
... và sau đó:
GET /example/123/last-update
<?xml version="1.0" encoding="UTF-8" ?>
<lastUpdate>
<resourceUri>/example/123</resourceUri>
<updatedBy uri="/user/321">321</updatedBy>
<updatedAt>2011-04-16 20:00:00 GMT</updatedAt>
</lastUpdate>
(. Trên đây có thể cũng độc đáo mở rộng để cung cấp một bản ghi kiểm toán đầy đủ với những thay đổi cá nhân, cung cấp một changelog tài nguyên có sẵn)
Xin lưu ý:
tôi đồng ý với Darrel Miller 's take on the question, nhưng tôi muốn pro vide một cách tiếp cận khác nhau trên đầu trang của nó. Lưu ý rằng cách tiếp cận này không được sao lưu bởi bất kỳ tiêu chuẩn/RFC/etc nào, đó chỉ là vấn đề khác.
Làm thế nào để bạn đại diện cho 'LastUser' và' LastUpdate' - chúng có phải là một phần của biểu diễn tài nguyên của bạn (tức là các nút trong XML) không? – MicE
không, chúng thậm chí không tồn tại khi issiung cập nhật, nhưng tôi trả lại khi truy vấn với một get .... vì vậy tôi tạo một PUT, và sau đó là GET và tôi nhận được thời gian lastUpdate, tôi lại phát hành lại PUT, và một GET mang lại một lastUpdate khác nhau ... – opensas
Ok, cảm ơn để xác nhận - xem câu trả lời của tôi dưới đây cho một thay thế về vấn đề này. – MicE