Mã phản hồi HTTP cho POST khi tài nguyên đã tồn tại


842

Tôi đang xây dựng một máy chủ cho phép khách hàng lưu trữ các đối tượng. Các đối tượng đó được xây dựng đầy đủ ở phía máy khách, hoàn thành với ID đối tượng là vĩnh viễn cho toàn bộ vòng đời của đối tượng.

Tôi đã xác định API để khách hàng có thể tạo hoặc sửa đổi các đối tượng bằng PUT:

PUT /objects/{id} HTTP/1.1
...

{json representation of the object}

{Id} là ID đối tượng, vì vậy nó là một phần của URI yêu cầu.

Bây giờ, tôi cũng đang xem xét cho phép khách hàng tạo đối tượng bằng POST:

POST /objects/ HTTP/1.1
...

{json representation of the object, including ID}

Vì POST có nghĩa là hoạt động "chắp thêm", tôi không chắc phải làm gì trong trường hợp đối tượng đã ở đó. Tôi nên coi yêu cầu là yêu cầu sửa đổi hay tôi nên trả lại một số mã lỗi (cái nào)?


5
Kể từ tháng 6 năm 2016 FB ngang nhiên đặt 200 khi đăng ký khi có email
Green

4
API Github trả về 422 khi cố gắng tạo tài nguyên (nhóm / repo) với tên đã được sử dụng
Ken

1
Nó phụ thuộc vào việc bạn xem sự tồn tại của đối tượng có lỗi hay không. Nếu bạn xử lý phần bổ sung, 200 hoặc 204 là mã phản hồi phù hợp nhất.
Suncat2000

Câu trả lời:


1056

Cảm giác của tôi là 409 Conflictthích hợp nhất, tuy nhiên, hiếm khi được nhìn thấy trong tự nhiên:

Yêu cầu không thể được hoàn thành do xung đột với trạng thái hiện tại của tài nguyên. Mã này chỉ được phép trong các tình huống mà người dùng dự kiến ​​có thể giải quyết xung đột và gửi lại yêu cầu. Cơ quan phản hồi NÊN bao gồm đủ thông tin để người dùng nhận ra nguồn gốc của xung đột. Lý tưởng nhất, thực thể phản hồi sẽ bao gồm đủ thông tin cho người dùng hoặc tác nhân người dùng để khắc phục sự cố; tuy nhiên, điều đó có thể là không thể và không bắt buộc.

Xung đột rất có thể xảy ra để đáp ứng yêu cầu PUT. Ví dụ: nếu phiên bản đang được sử dụng và thực thể là PUT bao gồm các thay đổi đối với tài nguyên xung đột với tài nguyên được tạo bởi yêu cầu trước đó (bên thứ ba), máy chủ có thể sử dụng phản hồi 409 để cho biết rằng nó không thể hoàn thành yêu cầu . Trong trường hợp này, thực thể phản hồi có thể sẽ chứa một danh sách các khác biệt giữa hai phiên bản theo định dạng được xác định bởi Kiểu nội dung phản hồi.


11
Tại sao không đi cho 400 Yêu cầu xấu? Đối với tôi điều này trông hơi giống một lỗi xác thực (bạn đang cung cấp tải trọng sai với id bất hợp pháp).
manuel aldana

314
400 => "Máy chủ không thể hiểu được yêu cầu do cú pháp không đúng" . Và máy chủ hiểu hoàn hảo, nhưng không thể tuân thủ do xung đột. Không có gì sai với yêu cầu & cú pháp, chỉ có một vấn đề dữ liệu. Một 400 sẽ ngay lập tức khiến tôi tin rằng toàn bộ cơ chế tôi đang sử dụng là thiếu sót, thay vì chỉ là dữ liệu.
Wrikken

42
@Wrikken Điều đó không còn đúng nữa. HTTP 400 đã được thay đổi trong RFC 7231 có nghĩa là "máy chủ không thể hoặc sẽ không xử lý yêu cầu do lỗi được coi là lỗi máy khách (ví dụ: cú pháp yêu cầu không đúng định dạng, khung tin nhắn yêu cầu không hợp lệ hoặc định tuyến yêu cầu lừa đảo)." Tôi không nói 400 là sử dụng đúng trong trường hợp này nhưng nó thể đúng với định nghĩa mới của 400.
javajavajavajavajava

19
@javajavajavajavajava: tuy nhiên, dữ liệu trùng lặp không phải là "lỗi máy khách" trong suy nghĩ của tôi, nhưng tất nhiên đó là trong mắt của kẻ si tình.
Wrikken

21
Tôi trở lại HTTP 409với một Locationtiêu đề chỉ đến tài nguyên hiện có / xung đột.
Gili

100

Theo RFC 7231 , 303 See Other CÓ THỂ được sử dụng Nếu kết quả xử lý POST sẽ tương đương với đại diện của tài nguyên hiện có .


4
Theo tôi, đây có thể là một câu trả lời được chấp nhận. Mặc dù "CÓ THỂ" chỉ ra một mục hoàn toàn tùy chọn, nhưng đó là mã phản hồi duy nhất được đề xuất bởi tài liệu chính thức của RFC 7231 .
Nando

16
Đây là câu trả lời RESTful nhất.
Seth

6
Tôi nghĩ bối cảnh là quan trọng. Ví dụ: trả về một số 30 ngụ ý chuyển hướng đến tài nguyên được tìm thấy là cần thiết. Điều đó có thể có ý nghĩa trong một cuộc gọi từ máy chủ đến máy chủ, nhưng nếu bạn đang chạy qua một quá trình đăng ký người dùng, nó sẽ không có ý nghĩa gì cả.
Trang web thẩm mỹ

11
Xin lỗi, tôi đang hạ thấp điều này. Các HTTP 300 là về chuyển hướng và chuyển hướng đến một đối tượng khác có thể có các thuộc tính khác nhau sẽ rất sai lệch.
Michael Scheper

6
Bạn không phải xin lỗi. Tuy nhiên, nếu biểu diễn tương đương với một tài nguyên hiện có, làm thế nào nó có thể có các thuộc tính khác nhau? Và thậm chí nếu nó có, làm thế nào một chuyển hướng sẽ gây hiểu lầm? OP nói: Tôi không chắc phải làm gì trong trường hợp đối tượng đã ở đó. Thực tế nó là đối tượng 'giống nhau'. Tại sao một chuyển hướng sẽ gây hiểu nhầm? Bạn đang nói về một đối tượng khác mà trong tâm trí của OP rõ ràng là không.
Nullius

86

Cá nhân tôi đi với phần mở rộng WebDAV 422 Unprocessable Entity.

Theo RFC 4918

Các 422 Unprocessable Entitymã trạng thái nghĩa là máy chủ hiểu được kiểu nội dung của đối tượng yêu cầu (do đó một 415 Unsupported Media Typemã trạng thái là không phù hợp), và cú pháp của tổ chức yêu cầu là chính xác (do đó một 400 Bad Requestmã trạng thái là không phù hợp) nhưng không thể xử lý các hướng dẫn kín.


19
Đây là một suy nghĩ thú vị và cuối cùng đã thôi thúc tôi đọc RFC của WebDAV. Tuy nhiên, tôi nghĩ rằng ý nghĩa của 422 là yêu cầu và thực thể bao gồm đã đúng về mặt cú pháp nhưng về mặt ngữ nghĩa không có ý nghĩa.
vmj

4
JSON không đúng định dạng không phải là một thực thể chính xác về mặt cú pháp, do đó, một 422cú đánh tôi là kỳ quặc ...
awendt 22/07/14

7
Tôi sẽ không đi với điều này. Từ cùng một URL được tham chiếu trong câu trả lời: "Ví dụ: điều kiện lỗi này có thể xảy ra nếu phần thân yêu cầu XML chứa định dạng chính xác (nghĩa là đúng về mặt cú pháp), nhưng sai về ngữ nghĩa, các lệnh XML." Đây là ý nghĩa thực sự của một thực thể không thể xử lý, không giống như trường hợp khi bạn gửi thực thể yêu cầu hoàn toàn hợp lệ với cú pháp VÀ ngữ nghĩa hợp lệ, nhưng vấn đề duy nhất là nó xung đột với một thực thể hiện có. Trên thực tế, nếu ngữ nghĩa của thực thể yêu cầu không hợp lệ, thì hoàn toàn không nên có một thực thể tương tự.
Tamer Shlash 4/12/2015

1
Thêm vào bình luận của Tamer, nếu yêu cầu thứ hai đến trước, thì nó sẽ thành công, điều đó sẽ không thể xảy ra nếu điều đó đúng về mặt ngữ nghĩa. Do đó trong ngữ nghĩa chính xác sẽ không áp dụng ở đây.
Harish

4
@Tamer Tại sao vậy? Lệnh "Hãy tạo đối tượng xy" về mặt cú pháp là chính xác. Nó chỉ đúng về mặt ngữ nghĩa nếu có thể tạo đối tượng xy. Nếu đối tượng xy đã tồn tại, nó không thể được tạo nữa, do đó đây là một lỗi ngữ nghĩa.
Hagen von Eitzen

48

Đó là tất cả về bối cảnh và cũng là người chịu trách nhiệm xử lý các bản sao trong các yêu cầu (máy chủ hoặc máy khách hoặc cả hai)


Nếu máy chủ chỉ trỏ trùng lặp , hãy xem 4xx:

  • 400 Yêu cầu Không hợp lệ - khi máy chủ không xử lý yêu cầu vì đó là lỗi máy khách rõ ràng
  • 409 Xung đột - nếu máy chủ sẽ không xử lý yêu cầu, nhưng lý do cho điều đó không phải là lỗi của khách hàng
  • ...

Để xử lý ngầm các bản sao, hãy xem 2XX:

  • 200 OK
  • 201 tạo
  • ...

nếu máy chủ dự kiến ​​sẽ trả lại một cái gì đó , hãy xem 3XX:

  • Tìm thấy 302
  • 303 Xem khác
  • ...

khi máy chủ có thể trỏ tài nguyên hiện có, nó ngụ ý chuyển hướng.


Nếu những điều trên là không đủ, thì luôn luôn là một cách tốt để chuẩn bị một số thông báo lỗi trong phần thân của phản hồi.


2
Yêu cầu không sao chép tài nguyên, nó đang nối thêm dữ liệu vào một tài nguyên. Theo tôi, của bạn là câu trả lời tốt nhất trong tất cả.
Suncat2000

28

Có thể muộn trò chơi nhưng tôi đã vấp phải vấn đề ngữ nghĩa này trong khi cố gắng tạo API REST.

Để mở rộng một chút về câu trả lời của Wrikken, tôi nghĩ bạn có thể sử dụng 409 Conflicthoặc 403 Forbiddentùy thuộc vào tình huống - tóm lại, sử dụng lỗi 403 khi người dùng hoàn toàn không thể làm gì để giải quyết xung đột và hoàn thành yêu cầu (ví dụ: họ không thể gửi DELETEyêu cầu xóa tài nguyên một cách rõ ràng) hoặc sử dụng 409 nếu có thể có thể thực hiện được.

10,4,4 403 Cấm

Máy chủ hiểu yêu cầu, nhưng từ chối thực hiện nó. Ủy quyền sẽ không giúp đỡ và yêu cầu KHÔNG NÊN lặp lại. Nếu phương thức yêu cầu không phải là CHÍNH và máy chủ muốn công khai lý do tại sao yêu cầu chưa được thực hiện, thì NÊN mô tả lý do từ chối trong thực thể. Nếu máy chủ không muốn cung cấp thông tin này cho khách hàng, mã trạng thái 404 (Không tìm thấy) có thể được sử dụng thay thế.

Ngày nay, có người nói "403" và vấn đề về quyền hoặc xác thực xuất hiện, nhưng thông số kỹ thuật nói rằng về cơ bản, máy chủ nói với khách hàng rằng họ sẽ không làm điều đó, đừng hỏi lại và đây là lý do khách hàng không nên hỏi lại 't.

PUTso với POST... POSTnên được sử dụng để tạo một phiên bản mới của tài nguyên khi người dùng không có phương tiện hoặc không nên tạo định danh cho tài nguyên. PUTđược sử dụng khi danh tính của tài nguyên được biết đến.

9,6 PUT

...

Sự khác biệt cơ bản giữa các yêu cầu POST và PUT được phản ánh theo nghĩa khác nhau của URI yêu cầu. URI trong yêu cầu POST xác định tài nguyên sẽ xử lý thực thể kèm theo. Tài nguyên đó có thể là một quá trình chấp nhận dữ liệu, một cổng vào một số giao thức khác hoặc một thực thể riêng biệt chấp nhận các chú thích. Ngược lại, URI trong yêu cầu PUT xác định thực thể kèm theo yêu cầu - tác nhân người dùng biết URI được dự định là gì và máy chủ KHÔNG cố gắng áp dụng yêu cầu cho một số tài nguyên khác. Nếu máy chủ mong muốn rằng yêu cầu được áp dụng cho một URI khác,

nó PHẢI gửi phản hồi 301 (Đã di chuyển vĩnh viễn); tác nhân người dùng CÓ THỂ đưa ra quyết định của riêng mình về việc có chuyển hướng yêu cầu hay không.


7
Tôi nghĩ 403 Forbidden ngụ ý rằng, mặc dù người dùng được xác thực , anh ta không được phép thực hiện hành động được yêu cầu. Tôi sẽ không sử dụng nó cho các lỗi xác nhận. Ví dụ : Chưa đăng nhập, tôi cố gắng xóa một cái gì đó. Server gửi cho tôi 401 Unauthorized (được chỉ nặng được đặt tên, nên 401 Unauthenticated ). Tôi đăng nhập và thử lại. Lần này máy chủ kiểm tra quyền của tôi, thấy tôi không được phép và trả về 403 Bị cấm . Cũng xem câu hỏi này .
Stijn de Witt

Hừm ... đúng rồi. Ý nghĩ ở đây là đúng khi nói với người dùng rằng các ủy quyền của họ làm cho tài nguyên không thay đổi trong trường hợp sử dụng của OP - nó đã tồn tại, bạn không có quyền làm bất cứ điều gì để giải quyết xung đột, đừng thử tạo lại tài nguyên.
p0lar_bear

3
Theo thông số kỹ thuật, hàm ý rằng lỗi 409 không thể được trả về bởi một POSTyêu cầu (khi được sử dụng đúng cách), vì nó nói rằng nó sẽ được trả về khi nó xung đột với tài nguyên đích . Vì tài nguyên đích chưa được đăng lên, nên nó không thể xung đột và do đó để trả lời 409 Conflictkhông có ý nghĩa gì.
Grant Gryczan

1
Tôi sẽ không suy luận rằng lỗi 409 không thể được trả về bởi POST, trên thực tế, tôi sẽ suy luận ngược lại vì "Xung đột rất có thể xảy ra khi đáp ứng yêu cầu PUT." dường như chỉ ra rằng các phương thức yêu cầu khác cũng có thể sử dụng mã này. Ngoài ra, "Cơ quan phản hồi nên bao gồm đủ thông tin để người dùng nhận ra nguồn gốc của xung đột. Lý tưởng nhất, thực thể phản hồi sẽ bao gồm đủ thông tin để người dùng hoặc tác nhân người dùng khắc phục sự cố; tuy nhiên, điều đó có thể không thể và là có thể không bắt buộc . " ( webdav.org/specs/rfc2616.html#status.409 )
JWAspin

14

"302 Found" nghe có vẻ hợp lý đối với tôi. Và RFC 2616 nói rằng nó CÓ THỂ được trả lời cho các yêu cầu khác ngoài GET và HEAD (và điều này chắc chắn bao gồm POST)

Nhưng nó vẫn giữ cho khách truy cập truy cập URL này để nhận tài nguyên "Tìm thấy" này, bởi RFC. Để làm cho nó đi trực tiếp đến URL "Đã tìm thấy" thực sự, bạn nên sử dụng "303 See Other", điều này có ý nghĩa, nhưng buộc một cuộc gọi khác phải NHẬN URL sau. Về mặt tốt, GET này là bộ nhớ cache.

Tôi nghĩ rằng tôi sẽ sử dụng "303 See Other" . Tôi không biết liệu tôi có thể phản hồi với "thứ" được tìm thấy trong cơ thể không, nhưng tôi muốn làm như vậy để lưu một vòng tròn vào máy chủ.

UPDATE: Sau khi đọc lại RFC, tôi vẫn nghĩ rằng một không tồn "4xx + 303 Found" mã nên là chính xác. Tuy nhiên, "Xung đột 409" là mã câu trả lời tốt nhất hiện có (được chỉ ra bởi @Wrikken), có thể bao gồm một tiêu đề Vị trí chỉ vào tài nguyên hiện có.


88
Trạng thái 3xx có nghĩa là để chuyển hướng
Aviram Netanel

1
"Tài nguyên được yêu cầu tạm thời nằm trong một URI khác." từ w3.org/Prot Protocol / rfc2616 / rfc2616
tượngofmike

1
IMHO, "307 Chuyển hướng tạm thời" là chuyển hướng tạm thời thực sự. "302" không rõ ràng, nhưng "FOUND !!" là thông điệp thực sự mong muốn ở đây. Sự thỏa hiệp rõ ràng nhất là "303 See Other" trên ngữ nghĩa HTTP. Tôi sẽ đi với "303 Xem khác".
alanjds

@DavidVartanian Hum ... Tôi không thấy lỗi ở đây. Khách hàng gửi yêu cầu đúng, nhưng làm thế nào để nói "Xin lỗi, nhưng những gì bạn đang cố gắng tạo ở đây đã tồn tại THÌ"? Có vẻ là một công việc cho một số 3xx. Nó không phải là 4xx đối với tôi, vì không có lỗi máy khách.
alanjds

1
@DavidVartanian Cảm ơn bạn đã thảo luận. Cập nhật câu trả lời cho 409 . Khách hàng đã sai khi yêu cầu những thứ không thể, ngay cả khi không biết rằng điều đó là không thể.
alanjds

11

Tôi không nghĩ bạn nên làm điều này.

POST, như bạn biết, để sửa đổi bộ sưu tập và nó được sử dụng để TẠO một mục mới. Vì vậy, nếu bạn gửi id (tôi nghĩ đó không phải là ý hay), bạn nên sửa đổi bộ sưu tập, nghĩa là sửa đổi mục, nhưng thật khó hiểu.

Sử dụng nó để thêm một mục, không có id. Đó là cách thực hành tốt nhất.

Nếu bạn muốn nắm bắt một ràng buộc ĐỘC ĐÁO (không phải id), bạn có thể trả lời 409, như bạn có thể làm trong các yêu cầu PUT. Nhưng không phải ID.


Điều gì về một đối tượng có mối quan hệ bảng tham gia? Giả sử chúng tôi có tài khoản, sản phẩm và account_product dưới dạng bảng cơ sở dữ liệu. Tôi muốn thêm một sản phẩm vào tài khoản, vì vậy tôi muốn đăng lên / account / {id} / sản phẩm với sản phẩm_id. Nếu chỉ cho phép một mối quan hệ sản phẩm tài khoản, tôi nên trả lại những gì?
partkyle

2
Quên các bảng cơ sở dữ liệu. Giả sử một sản phẩm chỉ có thể liên quan đến một tài khoản ... Sau đó, nó là một trong nhiều mối quan hệ. Vì vậy, POST / sản phẩm / {id} với {'tài khoản': account_id}. Nếu bạn có số lượng thẻ tối đa được đặt thành '1' (mối quan hệ một đối một) .... Tại sao chúng lại tách biệt các đối tượng? Một lỗi về cardinality sẽ chỉ là 400 lỗi. Giữ cho nó đơn giản. Tôi hy vọng tôi hiểu câu hỏi của bạn.
Alfonso Tienda

Tôi cũng chỉ đặt ra câu hỏi này và đối với tôi ID không phải là ID kỹ thuật trên cơ sở dữ liệu mà là một cái gì đó giống như mã công ty. Trong ứng dụng này, người dùng quản lý có thể tạo các công ty và phải cung cấp cho họ mã. Đây là ID công ty cho người dùng, mặc dù thực tế là bảng DB cũng có ID kỹ thuật. Vì vậy, trong trường hợp của tôi, tôi sẽ trả lại 409 nếu mã công ty tương tự đã tồn tại.
AlexCode

@partkyle Ngừng sử dụng PK làm ID công khai !!
Trang web thẩm mỹ

Một số thực thể có các ràng buộc duy nhất đối với chúng, không chỉ id. Giống như một tài khoản, bạn không thể tạo tài khoản nếu người dùng không cung cấp tên người dùng. Và việc thêm một tài khoản không có tên người dùng rõ ràng là không thể
rocketspacer

9

Tôi sẽ đi cùng 422 Unprocessable Entity, được sử dụng khi một yêu cầu không hợp lệ nhưng vấn đề không nằm ở cú pháp hoặc xác thực.

Là một đối số chống lại các câu trả lời khác, để sử dụng bất kỳ 4xxmã không lỗi nào sẽ ngụ ý đó không phải là lỗi của khách hàng và rõ ràng là như vậy. Để sử dụng 4xxmã không lỗi để biểu thị lỗi máy khách, không có nghĩa lý gì cả.

Có vẻ như 409 Conflict là câu trả lời phổ biến nhất ở đây, nhưng, theo thông số kỹ thuật, ngụ ý rằng tài nguyên đã tồn tại và dữ liệu mới mà bạn đang áp dụng cho nó không tương thích với trạng thái hiện tại của nó. Nếu bạn đang gửi mộtPOSTyêu cầu, ví dụ, với tên người dùng đã được sử dụng, nó không thực sự mâu thuẫn với tài nguyên đích, vì tài nguyên đích (tài nguyên bạn đang cố gắng tạo) chưa được đăng. Đó là lỗi đặc biệt đối với kiểm soát phiên bản, khi có xung đột giữa phiên bản tài nguyên được lưu trữ và phiên bản của tài nguyên được yêu cầu. Nó rất hữu ích cho mục đích đó, ví dụ như khi máy khách đã lưu trữ một phiên bản cũ của tài nguyên và gửi yêu cầu dựa trên phiên bản không chính xác đó sẽ không còn hợp lệ. "Trong trường hợp này, đại diện phản hồi có thể sẽ chứa thông tin hữu ích cho việc hợp nhất các khác biệt dựa trên lịch sử sửa đổi." Yêu cầu tạo một người dùng khác với tên người dùng đó là không thể xử lý được, không liên quan gì đến kiểm soát phiên bản.

Đối với bản ghi, 422 cũng là mã trạng thái mà GitHub sử dụng khi bạn cố gắng tạo một kho lưu trữ theo tên đã được sử dụng.


422 là thông số webdav vì vậy tôi không khuyên bạn nên sử dụng API này cho API REST
rwenz3l

7

Tôi nghĩ đối với REST, bạn chỉ cần đưa ra quyết định về hành vi cho hệ thống cụ thể đó, trong trường hợp đó, tôi nghĩ câu trả lời "đúng" sẽ là một trong những câu trả lời được đưa ra ở đây. Nếu bạn muốn yêu cầu dừng lại và hành xử như thể khách hàng đã mắc lỗi cần khắc phục trước khi tiếp tục, thì hãy sử dụng 409. Nếu xung đột thực sự không quan trọng và muốn tiếp tục yêu cầu, hãy phản hồi bằng cách chuyển hướng khách hàng đến thực thể đã được tìm thấy. Tôi nghĩ rằng các API REST thích hợp nên được chuyển hướng (hoặc ít nhất là cung cấp tiêu đề vị trí) đến điểm cuối GET cho tài nguyên đó sau POST, vì vậy hành vi này sẽ mang lại trải nghiệm nhất quán.

EDIT: Điều đáng chú ý là bạn nên xem xét PUT vì bạn đang cung cấp ID. Sau đó, hành vi rất đơn giản: "Tôi không quan tâm những gì ở đó ngay bây giờ, hãy đặt thứ này ở đó." Có nghĩa là, nếu không có gì ở đó, nó sẽ được tạo ra; nếu có cái gì đó nó sẽ được thay thế. Tôi nghĩ rằng POST phù hợp hơn khi máy chủ quản lý ID đó. Việc tách hai khái niệm về cơ bản cho bạn biết cách xử lý nó (ví dụ PUT là idempotent để nó luôn hoạt động miễn là tải trọng xác thực, POST luôn tạo, do đó, nếu có xung đột ID, thì 409 sẽ mô tả xung đột đó) .


Theo thông số kỹ thuật, hàm ý rằng lỗi 409 không thể được trả về bởi một POSTyêu cầu (khi được sử dụng đúng cách), vì nó nói rằng nó sẽ được trả về khi nó xung đột với tài nguyên đích . Vì tài nguyên đích chưa được đăng lên, nên nó không thể xung đột và do đó để trả lời 409 Conflictkhông có ý nghĩa gì.
Grant Gryczan

Imo gây tranh cãi. Nếu bạn đăng lên / người dùng thì tài nguyên là bộ sưu tập thay vì hồ sơ cá nhân / người dùng / {id}
Trang web thẩm mỹ

Đó là lỗi đặc biệt đối với kiểm soát phiên bản, khi có xung đột giữa phiên bản tài nguyên được lưu trữ và phiên bản của tài nguyên được yêu cầu. Nó rất hữu ích cho mục đích đó, ví dụ như khi máy khách đã lưu trữ một phiên bản cũ của tài nguyên và gửi yêu cầu dựa trên phiên bản không chính xác đó sẽ không còn hợp lệ. "Trong trường hợp này, đại diện phản hồi có thể sẽ chứa thông tin hữu ích cho việc hợp nhất các khác biệt dựa trên lịch sử sửa đổi."
Cấp Gryczan

Tôi thích đề nghị của bạn để sử dụng PUTmặc dù.
Cấp Gryczan

4

Một điều trị tiềm năng khác là sử dụng PATCH sau khi tất cả. Một PATCH được định nghĩa là một cái gì đó thay đổi trạng thái nội bộ và không bị hạn chế để nối thêm.

PATCH sẽ giải quyết vấn đề bằng cách cho phép bạn cập nhật các mục đã có. Xem: RFC 5789: VÒI


2
Bản vá giống như PUT nhưng không phải là sự thay thế hoàn toàn. Nó được sử dụng để sửa đổi một phần của tài nguyên như thêm, xóa hoặc sửa đổi một phần tử của tài nguyên thay vì thay thế toàn bộ tài nguyên.
Trang web thẩm mỹ

4

Tại sao không phải là 202 Chấp nhận ? Đó là một yêu cầu OK (200 giây), không có lỗi máy khách (400 giây), mỗi giây.

Từ 10 định nghĩa mã trạng thái :

"202 Được chấp nhận. Yêu cầu đã được chấp nhận để xử lý, nhưng quá trình xử lý chưa được hoàn thành."

... bởi vì nó không cần phải hoàn thành, bởi vì nó đã tồn tại. Khách hàng không biết nó đã tồn tại, họ không làm gì sai cả.

Tôi đang dựa vào việc ném 202 và trả lại nội dung tương tự với những gì GET /{resource}/{id}sẽ trả lại.


21
Câu trả lời này là sai. 202 có nghĩa là máy chủ không tìm thấy vấn đề với yêu cầu, nhưng đã chọn xử lý yêu cầu sau khi trả lời. Nó cũng có nghĩa là nó hy vọng rằng việc xử lý sẽ thành công. Trong trường hợp của chúng tôi, máy chủ biết rằng việc xử lý sẽ thất bại, vì vậy 202 là phản hồi sai.
Adrian

4
Một ví dụ về 202 sẽ là một hàng đợi hoặc đăng ký. Nói cách khác, kết quả của yêu cầu có thể không có sẵn ngay lập tức nếu bạn truy vấn nó ngay lúc này.
Trang web thẩm mỹ

1
Điều này sẽ phù hợp nếu máy chủ vẫn đang xử lý yêu cầu. 200 hoặc 204 sẽ phổ biến hơn. Vì OP đang thực hiện một yêu cầu chắp thêm, sự tồn tại của đối tượng là điều kiện mong đợi và không phải là lỗi.
Suncat2000

Không có ý nghĩa gì khi nói với khách hàng rằng yêu cầu đã được chấp nhận vì bạn đã biết rằng đó không phải là!
lucastamoios

1
@Adrian và lucastamoios Tôi nghĩ rằng cả hai bạn đều giả sử máy chủ đọc đồng bộ từ cơ sở dữ liệu, trước khi cung cấp phản hồi. Điều này không phải lúc nào cũng đúng, vì vậy câu trả lời này không "sai", vì máy chủ không phải lúc nào cũng "biết" về hồ sơ hiện có. Đây là trường hợp rất nhiều trong các hệ thống không đồng bộ trong đó lớp api chỉ đơn giản ghi lại các yêu cầu xử lý của các nhân viên nền.
gsaslis

2

Tình cờ gặp phải câu hỏi này trong khi kiểm tra mã chính xác cho bản ghi trùng lặp.

Xin tha thứ cho sự thiếu hiểu biết của tôi nhưng tôi không hiểu tại sao mọi người lại bỏ qua mã "300" có ghi rõ "nhiều lựa chọn" hoặc "mơ hồ"

Theo tôi đây sẽ là mã hoàn hảo để xây dựng một hệ thống không chuẩn hoặc cụ thể cho mục đích sử dụng của riêng bạn. Tôi cũng có thể sai!

https://tools.ietf.org/html/rfc7231#section-6.4.1


Hiểu biết của tôi: "mã trạng thái chỉ ra rằng tài nguyên đích có nhiều hơn một đại diện ... thông tin về các lựa chọn thay thế đang được cung cấp để người dùng (hoặc tác nhân người dùng) có thể chọn một đại diện ưa thích bằng cách chuyển hướng yêu cầu của nó đến một hoặc nhiều trong số đó định danh "Chúng tôi rõ ràng đang cố gắng ngăn chặn nhiều hơn một đại diện. Không có lựa chọn. Không có lựa chọn thay thế cho khách hàng để lựa chọn. Máy khách nên gửi lại với một id khác. Như đã nói, người ta cũng nên xem xét liệu id duy nhất có nên được tạo trong máy khách so với máy chủ hay không.
musicin3d

Về mặt ngữ nghĩa, máy khách đang nói "Tạo cái này" và máy chủ đang phản hồi bằng cách nói "Thay vào đây". Cuộc trò chuyện không có ý nghĩa gì. Gần như là máy chủ đang bảo khách "đăng lên vị trí này thay thế". 300 giây là một phản hồi thích hợp hơn đối với yêu cầu GET hoặc POST trong trường hợp máy chủ phản hồi với "Ok tôi đã tạo nó và nó ở đây" ..
Tạp chí Sina

2

Nhiều khả năng nó là 400 Bad Request

6.5.1. 400 yêu cầu xấu


Mã trạng thái 400 (Yêu cầu xấu) chỉ ra rằng máy chủ không thể hoặc sẽ không xử lý yêu cầu do lỗi được coi là lỗi máy khách (ví dụ: cú pháp yêu cầu không đúng định dạng, đóng khung thông báo yêu cầu không hợp lệ hoặc định tuyến yêu cầu lừa đảo).

Vì yêu cầu chứa giá trị trùng lặp (giá trị đã tồn tại), nên nó có thể được coi là lỗi máy khách. Cần thay đổi yêu cầu trước lần thử tiếp theo.
Bằng cách xem xét những sự thật này, chúng tôi có thể kết luận là Yêu cầu xấu HTTP STATUS 400.


1
Yêu cầu xấu có nghĩa là có một vấn đề cố hữu với cú pháp của gói. Nếu, trong một bối cảnh khác (chẳng hạn như tài nguyên chưa tồn tại), gói sẽ thành công, thì nó sẽ không trả về lỗi 400.
Grant Gryczan

1

Điều gì về 208 - http://httpstatusdogs.com/208-al yet - report ? Đó có phải là một lựa chọn?

Theo tôi, nếu điều duy nhất là tài nguyên lặp lại thì không có lỗi nào được nêu ra. Rốt cuộc, không có lỗi nào ở phía máy khách hay máy chủ.


Đây không phải là tùy chọn do bạn muốn nối thêm một mục nhất định mà id đã tồn tại. Vì vậy, bạn cố gắng thêm một cái gì đó nhưng điều này đã có sẵn. Một OK sẽ chỉ được áp dụng nếu tập dữ liệu được phát triển. Nối một cái gì đó -> Ok tôi không nối thêm gì. Không phù hợp, tôi đoán.
Martin Kersten

Như tôi đã nói, tôi không nghĩ đây là một lỗi. Nhưng tôi thấy quan điểm của @martin
Fernando Ferreira

Nếu tài nguyên không được tạo thành công, thì theo định nghĩa sẽ có lỗi.
Grant Gryczan

POST cũng được sử dụng để nối thêm dữ liệu. Đây là theo định nghĩa , không phải là một lỗi .
Suncat2000

@ Suncat2000 Ngay cả trong trường hợp đó, nếu dữ liệu không được nối thành công, vẫn có lỗi. Và nếu tài nguyên đã tồn tại, sẽ không có dữ liệu nào được thêm vào.
Grant Gryczan

0

Trong trường hợp của bạn, bạn có thể sử dụng 409 Conflict

Và nếu bạn muốn kiểm tra một HTTPsmã trạng thái khác từ danh sách bên dưới

Thông tin 1 ×

100 Continue
101 Switching Protocols
102 Processing

Thành công 2 ×

200 OK
201 Created
202 Accepted
203 Non-authoritative Information
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status
208 Already Reported
226 IM Used

Chuyển hướng 3 ×

300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
305 Use Proxy
307 Temporary Redirect
308 Permanent Redirect

Lỗi máy khách 4 ×

400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Payload Too Large
414 Request-URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfiable
417 Expectation Failed
418 I’m a teapot
421 Misdirected Request
422 Unprocessable Entity
423 Locked
424 Failed Dependency
426 Upgrade Required
428 Precondition Required
429 Too Many Requests
431 Request Header Fields Too Large
444 Connection Closed Without Response
451 Unavailable For Legal Reasons
499 Client Closed Request

Lỗi máy chủ 5 ×

500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates
507 Insufficient Storage
508 Loop Detected
510 Not Extended
511 Network Authentication Required
599 Network Connect Timeout Error
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.