REST có thể trả lại nội dung sau khi ĐĂNG không?


88

Tôi đang sử dụng RESTlet và tôi đã tạo một tài nguyên. Tôi xử lý POST bằng acceptRepresentationphương pháp ghi đè .

Máy khách sẽ gửi cho tôi một số dữ liệu, sau đó tôi lưu trữ nó vào DB, đặt phản hồi thành 201 (SUCCESS_CREATED) và tôi cần trả lại một số dữ liệu cho máy khách, nhưng kiểu trả về acceptRepresentationvoid.

Trong trường hợp của tôi, tôi cần trả lại một số bộ định danh để khách hàng có thể truy cập tài nguyên đó.

Ví dụ: nếu tôi có một tài nguyên có URL /resourcevà khách hàng gửi yêu cầu POST, tôi sẽ thêm một hàng mới trong DB và địa chỉ của nó phải có /resource/{id}. Tôi cần gửi {id}.

Tôi có làm điều gì sai? Các nguyên tắc REST có cho phép trả lại thứ gì đó sau khi POST không? Nếu có, tôi có thể làm như thế nào, và nếu không có cách xử lý tình huống này là gì?


Xem câu trả lời của Thom để biết cách thiết lập cơ quan phản hồi từ bên trong acceptRepresentation ().
Avi Flax

Câu trả lời:


96

REST chỉ nói rằng bạn nên tuân theo giao diện thống nhất. Nói cách khác, nó cho biết bạn nên làm những gì POST phải làm theo thông số HTTP . Đây là trích dẫn từ thông số kỹ thuật đó có liên quan,

Nếu tài nguyên đã được tạo trên máy chủ gốc, phản hồi NÊN là 201 (Đã tạo) và chứa một thực thể mô tả trạng thái của yêu cầu và đề cập đến tài nguyên mới và tiêu đề Vị trí (xem phần 14.30).

Như bạn có thể thấy từ điều này, bạn có hai nơi mà bạn có thể chỉ ra cho khách hàng nơi tài nguyên mới được tạo ra. Tiêu đề Vị trí phải có URL trỏ đến tài nguyên mới và bạn cũng có thể trả về một thực thể với các chi tiết.

Tôi không chắc sự khác biệt giữa ghi đè acceptRepresentation () và ghi đè post () nhưng ví dụ này cho thấy cách trả lại phản hồi từ POST.


2
@ del-boy: Xem câu trả lời của Thom để biết cách thiết lập cơ quan phản hồi từ bên trong acceptRepresentation ().
Avi Flax

1
Trích dẫn thông số kỹ thuật HTTP không cấm phản hồi, nếu bạn xem trong Phần 6 thì sẽ thấy rõ điều đó: nó được phép: Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code. An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.
MikeF

@MikeF Tôi không có ý định suy luận rằng cơ quan phản hồi không được phép. Phần thông số kỹ thuật tôi đã trích dẫn cụ thể nói rằng "và chứa một thực thể". Tôi lẽ ra phải rõ ràng hơn trong văn bản của mình.
Darrel Miller

16

Tôi đã bỏ qua việc gửi bất kỳ thứ gì trong nội dung phản hồi. Chỉ cần đặt Vị trí: thành URL (đầy đủ) của tài nguyên mới được tạo.

Mô tả của bạn cho thấy rằng đây chính xác là ngữ nghĩa mà bạn:

  1. ĐĂNG một thứ để tạo nó
  2. Trả lời đủ để biết hai điều:
    1. Rằng sự sáng tạo đã xảy ra (năm 201)
    2. Nơi để tìm thứ mới (tiêu đề Vị trí)

Bất cứ điều gì khác là thừa.


Không phải Wikipedia luôn là một nguồn tốt, nhưng điều đó cũng khẳng định "[...] Để cung cấp thông tin về vị trí của một tài nguyên mới được tạo. Trong trường hợp này, tiêu đề Vị trí phải được gửi với mã trạng thái HTTP là 201 hoặc 202 . "
Arjan

1
POST có thể thực thi logic tạo ra một hoặc nhiều tài nguyên. Khách hàng có thể cần kết quả của quá trình xử lý. Vì vậy, trả lại nó trong phản hồi sẽ tránh phải thực hiện một hoặc nhiều lệnh gọi GET tới API. Dữ liệu được tạo / thay đổi bằng phương thức POST có thể không (và thường không) thừa đối với máy khách.
Paulo Merson

10

Hai câu hỏi khác nhau:

Mẫu ứng dụng REST có hỗ trợ trả lại dữ liệu trong POST không?

Tôi không nghĩ rằng REST rõ ràng không cho phép nó, nhưng cách điều trị ưa thích được nêu rõ trong câu trả lời của Darrel.

Khung công tác RESTlet có cho phép trả về dữ liệu trong POST không?

Có, ngay cả khi nó trả về void, trong một lớp mở rộng Resource, bạn có toàn quyền truy cập vào đối tượng Response object thông qua phương thức getResponse (). Vì vậy, bạn có thể gọi getResponse (). SetEntity () với bất kỳ dữ liệu nào bạn muốn.


6

Xuất nó ở bất kỳ định dạng nào được yêu cầu. Đó có thể là:

<success>
    <id>5483</id>
</success>

Hoặc là:

{ "type": "success", "id": 5483 }

Nó phụ thuộc vào những gì bạn thường làm. Nếu họ không mong đợi dữ liệu, họ chỉ nên bỏ qua nó, nhưng bất kỳ khách hàng nào muốn xử lý nó đúng cách đều có thể.


Ok, tôi có hai định dạng có thể có (html và xml). Tôi biết cách xử lý loại định dạng được yêu cầu, nhưng tôi không biết cách thêm dữ liệu vào phản hồi. Phương thức đại diện trả về Đại diện, vì vậy tôi chỉ trả lại những gì tôi muốn, nhưng acceptRepresentation là phương thức void, vì vậy tôi không thể trả lại bất kỳ dữ liệu nào ...
del-boy

1

Nếu bạn trả lời 201 Được tạo bằng một cơ thể thực thể, thay vì chuyển hướng Vị trí, thì bạn nên bao gồm tiêu đề Nội dung-Vị trí trỏ đến tài nguyên đang được trình bày trong phản hồi.

Điều này sẽ tránh được sự nhầm lẫn tiềm ẩn - trong đó khách hàng có thể (chính đáng) giả định rằng thực thể phản hồi thực sự đại diện cho trạng thái mới của 'người tạo', chứ không phải tài nguyên được tạo.

> POST /collection
> ..new item..

< 201 Created
< Location: /collection/1354
< Content-Location: /collection/1354
< <div class="item">This is the new item that was created</div>

3
Tôi nghĩ Nội dung-Vị trí dành cho một mục đích khác. Thông số HTTP cho biết Nội dung-Vị trí không được xác định cho POST và PUT. Tiêu đề Vị trí được sử dụng với 201-Create. Việc quay lại Vị trí không tự động thực hiện chuyển hướng, bạn cần mã phản hồi 3XX cho việc đó.
Darrel Miller

1
Tiêu đề vị trí được sử dụng (trong một phản hồi 201) để cho biết tài nguyên đã tạo nằm ở đâu; nó không liên quan đến cơ quan thực thể của phản hồi mà nó đi kèm. Ý của tôi là - nếu bạn muốn bao gồm tài nguyên đã tạo trong chính phản hồi 201 (thay vì chuyển hướng / chuyển hướng máy khách đến một URI khác) thì tiêu đề vị trí nội dung sẽ là một ý tưởng hay. Điều này có thể là 'bẻ cong các quy tắc' một chút, nhưng nó hiệu quả hơn so với việc yêu cầu một chu kỳ yêu cầu / phản hồi khác để đưa trạng thái của tài nguyên mới đến máy khách.
Mike

Có ý nghĩa với tôi. Tôi chưa bao giờ sử dụng tiêu đề Nội dung-Vị trí trước đây.
Darrel Miller

nếu khách hàng là người sử dụng trình duyệt, việc trả về 201 với tiêu đề Vị trí không có ý nghĩa gì. Người dùng sẽ không biết phải làm gì với nó. nếu khách hàng là rô bốt, nó có thể được lập trình để biết cách đối phó với nó - giống như theo dõi GET on the Location.
chối cãi

3
@irreputable: Tôi tin rằng REST được dùng để thiết kế các API, trong đó A không phải là Tác nhân người dùng tìm kiếm một số HTML để hiển thị.
Hermes
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.