Khi nào nên sử dụng mã trạng thái HTTP 404 trong API


58

Tôi đang làm việc trên một dự án và sau khi tranh cãi với mọi người tại nơi làm việc khoảng hơn một giờ. Tôi quyết định biết những người trao đổi ngăn xếp có thể nói gì.

Chúng tôi đang viết một API cho một hệ thống, có một truy vấn sẽ trả về một cây Tổ chức hoặc một cây Mục tiêu.

Cây của Tổ chức là tổ chức mà người dùng có mặt, Nói cách khác, cây này phải luôn tồn tại. Trong tổ chức, một cây mục tiêu nên luôn luôn có mặt. (đó là nơi tranh luận bắt đầu). Trong trường hợp cây không tồn tại, đồng nghiệp của tôi đã quyết định rằng sẽ trả lời đúng với mã trạng thái 200. Và sau đó bắt đầu yêu cầu tôi sửa mã của mình vì ứng dụng bị đổ khi không có cây.

Tôi sẽ cố gắng để ngọn lửa và giận dữ.

Tôi đề nghị tăng lỗi 404 khi không có cây. Ít nhất nó sẽ cho tôi biết rằng có điều gì đó không ổn. Khi sử dụng 200, tôi phải thêm kiểm tra đặc biệt vào phản hồi của mình trong cuộc gọi lại thành công để xử lý lỗi. Tôi đang mong đợi nhận được một đối tượng, nhưng tôi thực sự có thể nhận được phản hồi trống vì không tìm thấy gì. Nghe có vẻ hoàn toàn công bằng khi đánh dấu phản hồi là 404. Và sau đó chiến tranh bắt đầu và tôi nhận được thông báo rằng tôi không hiểu lược đồ mã trạng thái HTTP. Vì vậy, tôi ở đây và hỏi có gì sai với 404 trong trường hợp này? Tôi thậm chí còn nhận được lập luận "Không tìm thấy gì, vì vậy việc trả lại 200" là đúng. Tôi tin rằng nó sai vì cây luôn luôn có mặt. Nếu chúng tôi không tìm thấy gì và chúng tôi đang mong đợi một cái gì đó, thì đó phải là 404.

Thêm thông tin,

Tôi quên thêm các url được tìm nạp.

Tổ chức

/OrgTree/Get

Bàn thắng

/GoalTree/GetByDate?versionDate=...
/GoalTree/GetById?versionId=...

Sai lầm của tôi, cả hai tham số được yêu cầu. Nếu bất kỳ phiên bản Ngày nào có thể được phân tích cú pháp đến một ngày được cung cấp, nó sẽ trả về bản sửa đổi đóng. Nếu bạn nhập một cái gì đó trong quá khứ, nó sẽ trả về phiên bản đầu tiên. Nếu bằng Id với id không tồn tại, tôi nghi ngờ nó sẽ trả về phản hồi trống với 200.

Thêm

Ngoài ra, tôi tin rằng câu trả lời tốt nhất cho vấn đề là tạo các đối tượng mặc định khi các tổ chức được tạo, không có cây nào không phải là trường hợp hợp lệ và nên được coi là một hành vi không xác định. Không có cách nào một tài khoản có thể được sử dụng mà không có cả hai cây. Vì lý do đó, họ nên luôn luôn có mặt.

Ngoài ra tôi đã liên kết này (một cái tương tự nhưng tôi không thể tìm thấy nó)

http://viswaug.files.wordpress.com/2008/11/http-headers-status1.png


Xin làm rõ: làm thế nào để ứng dụng có thể sụp đổ khi không có cây, nếu luôn có một cây theo điều kiện tiên quyết ? (Tôi đồng ý với bạn, nó trông giống như một 404)
Andres F.

Chà, mã không kiểm tra null và đang phân tích chuỗi json và dưới dạng đối tượng. Tại một số vị trí trong mã, đối tượng "được tải" không xuất hiện vì không thể tìm thấy nội bộ.
Loïc Faure-Lacroix

4
Sẽ rõ ràng hơn nếu bạn cung cấp URI cho tài nguyên bạn đang cố truy cập. Nếu đó là / mục tiêu / bạn trả lại 200 và đặt trống. Nếu bạn đang cố truy cập / mục tiêu / {Goal_id} thì bạn trả về 404. Nếu bạn trả lại 404 cho yêu cầu cho / mục tiêu /, điều đó có nghĩa là URI không tồn tại và không nên sử dụng nữa.
imel96

1
Vẫn trong cả hai trường hợp câu hỏi giữ. Nên /GoalTree/GetById?versionId=CompletelyInvalidIDtrả lại cái gì? Không thành công, vì tài nguyên được đặt tên theo /GoalTree/GetById?versionId=CompletelyInvalidIDnghĩa đen là không tìm thấy.

2
Tuyệt vời, bây giờ các cuộc thảo luận đã chuyển từ công việc của bạn sang quốc tế! Nó là không thể ngăn chặn bây giờ!
Carlos Campderrós

Câu trả lời:


80

Khi nghi ngờ, tham khảo tài liệu . Việc xem xét các định nghĩa W3C cho mã Trạng thái HTTP, cung cấp cho chúng tôi điều này:

200 OK - Yêu cầu đã thành công. Thông tin được trả về với phản hồi phụ thuộc vào phương thức được sử dụng trong yêu cầu.

404 Không tìm thấy - Máy chủ không tìm thấy bất cứ thứ gì khớp với URI yêu cầu.

Trong ngữ cảnh API của bạn, nó phụ thuộc rất nhiều vào cách tạo truy vấn và cách truy xuất đối tượng. Nhưng, cách giải thích của tôi luôn luôn là:

  • Nếu tôi yêu cầu một đối tượng cụ thể và nó tồn tại 200mã trả về , nếu nó không tồn tại trả về 404mã chính xác .
  • Nhưng, nếu tôi yêu cầu một tập hợp các đối tượng khớp với truy vấn, thì tập hợp null là một phản hồi hợp lệ và tôi muốn trả về bằng một 200mã. Lý do cho điều này là truy vấn hợp lệ, nó đã thành công và truy vấn không trả về gì.

Vì vậy, trong trường hợp này bạn đúng , dịch vụ không tìm kiếm "một điều cụ thể" mà nó đang yêu cầu một điều cụ thể, nếu điều đó không được tìm thấy nói rõ điều đó.

Tôi nghĩ Wikipedia đặt nó tốt nhất:

200 OK - ... Phản hồi thực tế sẽ phụ thuộc vào phương thức yêu cầu được sử dụng. Trong yêu cầu GET, phản hồi sẽ chứa một thực thể tương ứng với tài nguyên được yêu cầu.

404 Không tìm thấy - Không thể tìm thấy tài nguyên được yêu cầu nhưng có thể sẽ có sẵn một lần nữa trong tương lai. Các yêu cầu tiếp theo của khách hàng được cho phép.

Có vẻ khá rõ ràng với tôi.

Về các yêu cầu ví dụ

/GoalTree/GetByDate?versionDate=...
/GoalTree/GetById?versionId=...

Đối với định dạng, bạn nói, bạn luôn trả lại bản sửa đổi gần nhất cho đến ngày đó. Nó sẽ không bao giờ không trả lại một đối tượng, vì vậy nó sẽ luôn luôn trở lại 200 OK. Ngay cả khi điều này có thể lấy phạm vi ngày và logic là trả về tất cả các đối tượng trong khung thời gian đó trả về 200 OK - 0 Kết quả vẫn ổn, vì đó là yêu cầu dành cho - tập hợp những điều đáp ứng tiêu chí đó.

Tuy nhiên, cái sau thì khác khi bạn yêu cầu một đối tượng cụ thể , có lẽ là duy nhất, với danh tính đó. Trở lại 200 OKtrong trường hợp này là sai vì tài nguyên được yêu cầu không tồn tại và không được tìm thấy .

Về việc chọn mã trạng thái

  • Mã 2xx Nói với một UA rằng nó đã làm đúng , yêu cầu đã hoạt động. Nó có thể tiếp tục làm điều này trong tương lai.
  • Mã 3xx Hãy nói với UA những gì bạn yêu cầu có thể được sử dụng để làm việc, nhưng điều đó bây giờ ở nơi khác. Trong tương lai, UA có thể cân nhắc việc chuyển hướng .
  • Mã 4xx Hãy nói với UA rằng nó đã làm sai , yêu cầu mà nó tạo ra không phù hợp và không nên thử lại, mà không cần sửa đổi ít nhất.
  • Mã 5xx Hãy nói với UA máy chủ bị hỏng bằng cách nào đó . Nhưng hey truy vấn đó có thể hoạt động trong tương lai, vì vậy không có lý do gì để không thử lại. (ngoại trừ 501, nhiều hơn 400 vấn đề).

Bạn đã đề cập trong một nhận xét bằng mã 5xx, nhưng hệ thống của bạn đang hoạt động. Nó đã được hỏi một truy vấn không hoạt động và cần truyền đạt điều đó đến UA. Bất kể bạn cắt nó như thế nào, đây là lãnh thổ 4xx.

Hãy xem xét một người ngoài hành tinh truy vấn hệ mặt trời của chúng ta

Người ngoài hành tinh: Máy tính, xin vui lòng cho tôi biết tất cả các hành tinh mà con người sinh sống.

Máy tính: 1 kết quả được tìm thấy. Trái đất

Người ngoài hành tinh: Máy tính, xin vui lòng cho tôi biết về Trái đất .

Máy tính: Trái đất - Chủ yếu là vô hại.

Người ngoài hành tinh: Máy tính, xin vui lòng cho tôi biết về tất cả các hành tinh con người sinh sống, bên ngoài vành đai tiểu hành tinh.

Máy tính: tìm thấy 0 kết quả.

Người ngoài hành tinh: Máy tính, hãy tiêu diệt Trái đất.

Máy tính: 200 OK.

Người ngoài hành tinh: Máy tính, xin vui lòng cho tôi biết về Trái đất .

Máy tính: 404 - Không tìm thấy

Người ngoài hành tinh: Máy tính, xin vui lòng cho tôi biết tất cả các hành tinh mà con người sinh sống.

Máy tính: tìm thấy 0 kết quả.

Người ngoài hành tinh: Chiến thắng cho Đế chế Irken hùng mạnh!


4
+1 Đây không phải là truy vấn không trả về kết quả. Điều này giống như yêu cầu trình duyệt cho một trang web đã biết và không tìm thấy nó. Chính xác những gì 404 là có.
Andres F.

2
@ imel96 bạn quên rằng chuỗi truy vấn là một phần của URL.
Loïc Faure-Lacroix

1
@LegoStormtroopr Ví dụ "người ngoài hành tinh" thú vị của bạn hoạt động vì vũ trụ KHÔNG hợp lệ khi Trái đất không tồn tại. Nhưng theo lời giải thích của OP, hệ thống của anh ta phải bao gồm cả cây. Không có cây, hệ thống không hoạt động.
Andres F.

1
@LegoStormtroopr hãy tưởng tượng một bảng cơ sở dữ liệu. Bạn truy vấn bảng, đôi khi bạn nhận được kết quả, đôi khi bạn không. Bảng là tài nguyên của bạn, nó luôn ở đó bất kể nó có trả về hàng hay không. Bảng có thể xác định được, nó có tên (như tài nguyên http có URI). Các hàng không, chúng chỉ khớp với một số tham số. Ngay cả trong cơ sở dữ liệu, nếu bạn thực hiện cập nhật không có gì, bạn sẽ nhận được "OK 0 hàng bị ảnh hưởng".
imel96

2
@LegoStormtroopr bạn đã có câu trả lời. Nếu họ muốn ánh xạ lại / GoalTree / GetById? VersionId = x, thì nó sẽ trả về 301 với tiêu đề Vị trí được đặt thành / GoalTree / Id / x.
imel96

11

Bỏ qua thực tế là / GoalTree / Get * trông giống như một động từ, không phải tài nguyên, bạn phải luôn trả về 200 vì URI / GoalTree / Get * đại diện cho các tài nguyên luôn có sẵn để truy cập và đó không phải là lỗi của máy khách nếu không có cây do một yêu cầu. Chỉ cần trả lại 200 với tập rỗng khi không có thực thể nào được trả về.

Bạn sử dụng 404 nếu không tìm thấy tài nguyên, không phải khi không có thực thể.

Đặt nó theo một cách khác, nếu bạn muốn trả về 404 cho các đối tượng của mình, sau đó cung cấp cho họ các URI của riêng họ.


1
Hừm. Điều này thật ý nghĩa. 404 là lỗi người dùng , nhưng như OP giải thích, đây thực sự là lỗi hệ thống ; yêu cầu của người dùng là hoàn toàn hợp lệ! Tôi không đồng ý 200 là phản hồi đúng, bởi vì "không có cây" là một lỗi .
Andres F.

@ imel96 Tôi muốn có các thực thể hợp lệ luôn được trả về thay vì trống / mã trạng thái 4xx / 5xx. Nếu đó chỉ là tôi, tôi sẽ trả lại một thực thể hợp lệ giống như wiki chẳng hạn. Ít đau đầu không cần xử lý lỗi. Vì nó là, tôi nói nó khá giống với 500. Hệ thống ở trạng thái không xác định, điều đó không nên xảy ra. Và trả lại OK không có ý nghĩa. 404 liên quan đến rfc cũng không có ý nghĩa. Vì vậy, khi không có ý nghĩa gì ... chỉ có 500 có ý nghĩa!
Loïc Faure-Lacroix

@Sybiam tốt, bạn đã yêu cầu mã trạng thái http được xác định rất rõ. Về vấn đề này, ngay cả khi logic kinh doanh của bạn nói rằng đó là lỗi, điều đó không có nghĩa là hệ thống như một máy chủ http có lỗi. Trong trường hợp của bạn, nó hiểu yêu cầu của bạn, nó đã xử lý truy vấn của bạn và kết quả là không có thực thể. Vì vậy, bạn cũng không thể sử dụng 500. Ít nhất là xem xét để cung cấp cho các đối tượng của mình các URI thích hợp và xem liệu rfc có ý nghĩa hơn hay không.
imel96

+1 Nếu bạn có API REST (mỗi thực thể có đường dẫn riêng) thì bạn có thể trả về 404, nhưng đường dẫn của bạn là động từ và sẽ luôn được tìm thấy.
Ngừng làm hại Monica

@OrangeDog: /GoalTree/GetById?versionId=12345 một URI hoàn toàn tốt (ít nhất là một tương đối, ít nhất), xác định một tài nguyên cụ thể, cụ thể là dữ liệu tương ứng với ID phiên bản 12345trong hệ thống. Nếu không có dữ liệu với ID như vậy tồn tại, phản hồi HTTP 404 là hoàn toàn phù hợp. Tất nhiên, trong mọi trường hợp, cơ quan phản hồi nên chứa một phản hồi được định dạng phù hợp (ví dụ JSON, nếu đó là những gì khách hàng điển hình yêu cầu các tài nguyên đó mong đợi) chỉ ra bản chất và nguyên nhân cụ thể của lỗi.
Ilmari Karonen

7

Đây là một câu hỏi thú vị, bởi vì đó là tất cả về đặc điểm kỹ thuật của hệ thống.

Phản hồi của imel96 đã thuyết phục tôi rằng 404 sẽ không phải là phản hồi phù hợp, vì họ mã 4xx chủ yếu là do lỗi người dùng / máy khách và đây không phải là lỗi. URL được hình thành tốt và cây phải ở đó; nếu không, hệ thống sẽ ở trạng thái không nhất quán!

Do đó, đây là một lỗi máy chủ , tức là một cái gì đó trong gia đình 5xx. Có thể là 500 Lỗi máy chủ nội bộ chung chung hoặc Dịch vụ 503 không khả dụng (dịch vụ đang "lấy cho tôi cây phải ở đó").


2
Không đúng, người dùng bị lỗi vì họ yêu cầu một cái gì đó không tồn tại .

@LegoStormtroopr Yêu cầu một cái gì đó không tồn tại không phải lúc nào cũng là một lỗi. Nếu bạn yêu cầu tài nguyên mạng và mạng bị hỏng thì đó là lỗi mạng .
Andres F.

1
@LegoStormtroopr Bên cạnh đó, cây phải tồn tại; hệ thống không thể hoạt động mà không có nó, theo giải thích của OP. Do đó, nó hợp lệ để yêu cầu tài nguyên này; nếu nó không ở đó, thì đó phải là lỗi hệ thống (hoặc máy chủ).
Andres F.

2
@Sybiam Nếu bạn định đi theo tuyến mã 5xx, 503 là "503 Dịch vụ không khả dụng - Máy chủ hiện không thể xử lý yêu cầu do quá tải tạm thời hoặc bảo trì máy chủ." Máy chủ của bạn không bị quá tải, nó không tìm thấy yêu cầu. Ngoài ra, mã 5xx dành cho khi "máy chủ biết rằng nó bị lỗi hoặc không có khả năng thực hiện yêu cầu"

1
@AresresF. Thành thật mà nói, một mã 500 có lẽ là tốt. Cho biết câu hỏi đã thay đổi theo thời gian như thế nào, nó sẽ hoạt động. Hầu hết, tôi chỉ tập hợp lại để trả lại 200 nếu mọi thứ không ổn.

6

Tôi muốn nói rằng mã phản hồi 200 hoặc 404 có thể hợp lệ , tùy thuộc vào cách bạn nhìn vào tình huống.

Vấn đề là mã phản hồi HTTP được xác định trong ngữ cảnh của một máy chủ , có thể phân phối các tài nguyên khác nhau dựa trên URL của chúng. Trong bối cảnh này, ý nghĩa của 200 OK404 Not Foundhoàn toàn không rõ ràng: cái trước nói "đây là tài nguyên bạn yêu cầu", trong khi cái sau nói "xin lỗi, tôi không có tài nguyên nào như vậy".

Tuy nhiên, trong tình huống của bạn, bạn có một lớp ứng dụng bổ sung giữa máy chủ HTTP và tài nguyên thực tế (cây) đang được yêu cầu. Ứng dụng chiếm một loại không gian trung gian không được xử lý tốt trong thông số HTTP.

Từ quan điểm của máy chủ web, ứng dụng sẽ loại như một nguồn tài nguyên: nó thường là một tập tin trên máy chủ, xác định bởi (một phần của) URL, giống như các nguồn lực khác (ví dụ như các file tĩnh) các máy chủ có thể phục vụ. Mặt khác, nó là một loại tài nguyên kỳ lạ, vì nó bao gồm mã thực thi xác định động nội dung và thực sự có khả năng ngay cả mã trạng thái, của phản hồi, khiến nó hoạt động theo một cách nào đó giống như một máy chủ mini.

Cụ thể, trong trường hợp ví dụ của bạn, máy chủ web có thể định vị ứng dụng tốt, nhưng sau đó ứng dụng không thể xác định được nguồn con (cây) đã được yêu cầu. Bây giờ, nếu bạn coi ứng dụng chỉ là một phần mở rộng của máy chủ và phần phụ (cây) là tài nguyên thực tế, thì phản hồi 404 là phù hợp: máy chủ chỉ ủy thác nhiệm vụ tìm tài nguyên thực tế cho ứng dụng , mà đến lượt nó đã thất bại để làm như vậy.

Mặt khác, nếu quan điểm của bạn là ứng dụng là tài nguyên đang được yêu cầu, thì rõ ràng máy chủ web sẽ trả về 200 phản hồi ; sau khi tất cả, ứng dụng đã được tìm thấy và thực hiện chính xác. Rõ ràng, trong trường hợp này, ứng dụng thực sự sẽ trả về phần thân phản hồi hợp lệ ở định dạng mong đợi, cho biết (sử dụng bất kỳ giao thức cấp cao hơn nào định dạng mã hóa) mà không tìm thấy dữ liệu thực tế phù hợp với truy vấn.

Cả hai quan điểm này có thể có ý nghĩa. Trong hầu hết các trường hợp , ít nhất là đối với các ứng dụng dự định được truy cập trực tiếp qua HTTP bằng trình duyệt web thông thường, tôi sẽ ủng hộ quan điểm trước đây : người dùng thường không quan tâm đến các chi tiết nội bộ như sự khác biệt giữa máy chủ và ứng dụng, họ chỉ quan tâm đến việc dữ liệu họ muốn có ở đó hay không.

Tuy nhiên, trong trường hợp cụ thể của một ứng dụng được thiết kế để giao tiếp với các chương trình máy tính khác sử dụng giao thức API cấp cao tùy chỉnh, chỉ sử dụng HTTP làm lớp vận chuyển cấp thấp , có một lý lẽ được đưa ra theo quan điểm sau : khách hàng can thiệp vào một ứng dụng như vậy, tất cả những gì họ thực sự quan tâm, ở cấp độ HTTP , là liệu họ có quản lý để liên lạc thành công với ứng dụng đó hay không. Mọi thứ khác là, trong những trường hợp như vậy, thường được giao tiếp tự nhiên hơn bằng cách sử dụng giao thức cấp cao hơn.


Trong mọi trường hợp, bất kể bạn thích quan điểm nào ở trên, có một vài chi tiết bạn nên ghi nhớ. Một là, trong nhiều trường hợp, có thể có sự phân biệt có ý nghĩa giữa tài nguyên trống (về cơ bản) và tài nguyên không tồn tại .

Ở cấp độ HTTP, một tài nguyên trống sẽ chỉ được biểu thị bằng mã phản hồi 200 và phần thân phản hồi trống, trong khi tài nguyên không tồn tại sẽ được biểu thị bằng phản hồi 404 và phần thân tài nguyên giải thích sự vắng mặt của tài nguyên. Trong giao thức API cấp cao hơn, người ta thường chỉ ra tài nguyên không tồn tại bằng phản hồi lỗi, chứa mã / thông báo lỗi cụ thể theo giao thức, trong khi phản hồi trống sẽ chỉ là cấu trúc phản hồi bình thường không có mục dữ liệu.

(Lưu ý rằng tài nguyên không cần phải bằng 0 byte theo nghĩa đen là "trống rỗng" theo nghĩa tôi muốn nói ở trên. Ví dụ: kết quả tìm kiếm không có mục phù hợp sẽ được tính là trống theo nghĩa rộng, cũng như kết quả truy vấn SQL với không có hàng hoặc tài liệu XML không chứa dữ liệu thực tế.)

Ngoài ra, tất nhiên, nếu ứng dụng thực sự tin rằng nguồn con được yêu cầu sẽ ở đó, nhưng không thể tìm thấy nó, thì mã phản hồi thứ ba có thể tồn tại : 500 Internal Server Error. Phản hồi như vậy có ý nghĩa nếu sự tồn tại của tài nguyên là điều kiện tiên quyết giả định cho ứng dụng, do đó sự vắng mặt của nó nhất thiết chỉ ra sự cố bên trong.

Cuối cùng, bạn nên luôn luôn ghi nhớ luật của Postel :

" Hãy thận trọng trong những gì bạn gửi, và tự do trong những gì bạn nhận được. "

Cho dù máy chủ sẽ phản hồi trong một tình huống cụ thể với phản hồi 200 hoặc 404, điều đó không cho phép bạn là người triển khai ứng dụng khách xử lý phản hồi một cách thích hợp và theo cách tối đa hóa khả năng tương tác mạnh mẽ. Tất nhiên, việc xử lý "phù hợp" có nghĩa là gì trong các tình huống khác nhau có thể được tranh luận, nhưng chắc chắn nó thường không bao gồm sự cố hoặc "sụp đổ".


Vấn đề nan giải cũng được giải thích.
Marcel

không có vấn đề nan giải. câu trả lời này không dựa trên tài nguyên nào được định nghĩa như trong rfc liên quan. xem bình luận của tôi dưới câu trả lời @LegoStormtroopr.
imel96

@ imel96: Tôi nghĩ rằng bạn đang hiểu sai RFC 1630: đoạn bạn trích dẫn trong nhận xét trước đó của bạn đọc đầy đủ: "Dấu hỏi ("? ", hexIIIIF) được sử dụng để phân định ranh giới giữa URI của truy vấn đối tượng và một tập hợp các từ được sử dụng để diễn tả một truy vấn trên đối tượng đó. Khi biểu mẫu này được sử dụng, URI kết hợp là viết tắt của đối tượng kết quả từ truy vấn được áp dụng cho đối tượng ban đầu. " (nhấn mạnh của tôi). Do đó, rõ ràng chuỗi truy vấn thực sự là một phần của URI (mặc dù phần trước chuỗi truy vấn, nhất thiết, cũng là một URI hợp lệ) ...
Ilmari Karonen

... Và rằng URI kết hợp này xác định một tài nguyên cụ thể mà khách hàng có thể yêu cầu bằng cách gửi URI đó đến máy chủ. Trong mọi trường hợp, RFC 2616 (HTTP) chỉ định nghĩa một tài nguyên là "Đối tượng hoặc dịch vụ dữ liệu mạng có thể được xác định bởi một URI, như được định nghĩa trong phần 3.2." và tiếp tục nói rằng "Liên quan đến HTTP, Mã định danh tài nguyên đồng nhất chỉ là các chuỗi được định dạng đơn giản xác định - thông qua tên, vị trí hoặc bất kỳ đặc điểm nào khác - một tài nguyên."
Ilmari Karonen

@IlmariKaronen bạn nói đúng. Tôi đã nhầm lẫn HTTP với REST. Mặc dù vậy vẫn có vẻ không đúng vì tôi không chắc bạn có thể làm gì với tài nguyên với URI như / GoalTree / Get? VersionDate = 2000BC
imel96

3

Làm thế nào về một 204 Không có nội dung? Nó sẽ đề nghị rằng yêu cầu của bạn đã được xử lý thành công nhưng không trả lại gì cả. Nó vẫn là một "thành công" nhưng cho phép bạn xem nếu bạn có kết quả chỉ dựa trên mã trạng thái.


6
nếu bạn đọc thêm thông số kỹ thuật, "Phản hồi này chủ yếu nhằm cho phép đầu vào cho các hành động diễn ra mà không gây ra thay đổi đối với chế độ xem tài liệu đang hoạt động của tác nhân người dùng". Vì vậy, nó không nên được sử dụng cho các yêu cầu GET.
imel96

3

Nếu URL đại diện cho tài nguyên chưa từng tồn tại, hãy trả về 404 Không tìm thấy

Nếu URL đại diện cho một tài nguyên là một danh sách trống, trả về một danh sách trống và 200 OK.

Thí dụ:

{
  total: 0,
  items: []
}

Nếu URL đại diện cho một tài nguyên được sử dụng để tồn tại, hãy trả về 410 Gone.

Về hộp thoại của Lego Stormtrooper:

Alien: Computer, please tell me all planets that humans inhabit. GET /planets?inhabitedBy=humans

Computer: 200 OK. { total: 1, items:[{name:'Earth'}] }

Alien: Computer, please tell me about Earth. GET /planets/earth

Computer: 200 OK. {name:'Earth', status: 'Mostly Harmless'}

Alien: Computer, please tell me about all planets humans inhabit, outside the asteroid belt. GET /planets?inhabitedBy=humans&distanceFromSun=lots

Computer: 200 OK. {total:0, items:[] }

Alien: Computer, please destroy Earth. DELETE /planets/earth

Computer: 204 No Content. (or 202 Accepted if it takes some time to destroy Earth)

Alien: Computer, please tell me about Earth. GET /planets/earth

Computer: 410 Gone

Alien: Computer, please tell me all planets that humans inhabit. GET /planets?inhabitedBy=humans

Computer: 200 OK 0 {total: 0, items:[] }

Alien: Victory for the mighty Irken Empire!

1

Từ âm thanh của nó, đây là một API để sử dụng nội bộ . Điều này mang lại lợi thế cho việc sử dụng lược đồ nào mang lại lợi ích cao nhất , bất kể đó là sách phụ (đặc tả) hay không. Điều này không có nghĩa là hoàn toàn phát minh ra mã trạng thái của riêng bạn, nhưng bạn có thể 'bẻ cong' các quy tắc một chút nếu nó có lợi.

Tôi đồng ý với quan điểm của bạn rằng bạn sẽ nhận được một mã trạng thái cho thấy có gì đó không ổn. Đây là sau khi tất cả các mã trạng thái là dành cho. Ngoài ra, bạn nhận được lợi ích của các thư viện ném ngoại lệ / vv. trên mã trạng thái không phải 200 để bạn không phải kiểm tra rõ ràng (Hoặc bạn có thể viết trình bao bọc của riêng bạn thực hiện việc này).

Tôi cũng đồng ý với quan điểm của Andres F. rằng 500 là phù hợp vì cây nên tồn tại. Trong thực tế, tôi muốn chia các lỗi máy chủ thành hai loại. Một cái gì đó bất ngờ đã đi sai và một cái gì đó mà tôi thực tế có thể kiểm tra đã đi sai. Điều này dẫn đến các mã trạng thái sau đây,

  • 200 - Mọi thứ đều tốt
  • 404 - Sai url
  • 409 - Đã xảy ra lỗi
  • 500 - Xảy ra lỗi không mong muốn trên máy chủ

Trong trường hợp cụ thể của bạn, bạn có thể kiểm tra xem cây có tồn tại hay không ở phía máy chủ và nếu không có thì trả về 409. Đó là một lỗi dự kiến ​​(bạn biết nó có thể xảy ra, bạn có thể kiểm tra nó, v.v.) . Xung đột 409 chỉ là sở thích cá nhân của tôi, 5xx cũng có thể phù hợp miễn là bạn có thể ngồi xuống và quyết định điều này với nhóm của mình.

Phân loại mã như thế này giúp bạn nhanh chóng xác định loại lỗi, nhưng nó có thể có lợi ích ngoài tổ chức. Thông thường với các lỗi trang web, bạn không muốn máy khách gặp lỗi không mong muốn vì đây có thể là vấn đề bảo mật và tiết lộ lỗ hổng để bạn trả lại 500 "Lỗi xảy ra chung". và ghi lại lỗi đầy đủ trên máy chủ. Nhưng nếu một lỗi dự kiến ​​xảy ra là 409, bạn biết rằng sẽ an toàn khi hiển thị lỗi cho khách hàng và bạn không phải để chúng trong bóng tối như những gì đã xảy ra. Đây chỉ là một ứng dụng thực tế tôi có thể kể lại, nhưng có rất nhiều khả năng.

Đây là một chút hấp dẫn bởi vì bạn đang đăng bài này do không thể đồng ý với đồng nghiệp của bạn, nhưng có vẻ như các bạn đang tranh luận nhiều hơn về ngữ nghĩa và chính xác. Nó thực sự không quan trọng ai là người phù hợp hơn, miễn là bạn có thể đưa ra một hệ thống có lợi nhất cho công ty.

Mặt khác, nếu đây là một API công khai tuân theo các thông số kỹ thuật càng gần càng tốt sẽ càng quan trọng hơn để tránh sự nhầm lẫn trong cộng đồng.


0

Thực hiện một cú đâm tiếp tuyến vào việc này: Nếu cuối cùng con người sử dụng API (thông qua GUI) tôi sẽ đề nghị làm bất cứ điều gì giúp cuộc sống của người dùng cuối trở nên dễ dàng. Sự không tồn tại của cây khi nó tồn tại là một lỗi "không nhất quán mô hình miền". Một lỗi hệ thống là khi bạn hết bộ nhớ hoặc có một số lỗi hệ thống khác. Vì vậy, trả lại 5xx là không phù hợp. Như đã đề cập bởi một số người ở trên, 4xx có thể phù hợp nếu bản thân cây có URI riêng, không phải là trường hợp ở đây. Nhưng đây là những gì 404 nói với khách hàng: bạn có thể thử đi thử lại cho đến khi bạn nhận lại được điều gì đó. Nếu bạn trả về 200, bạn có thể trả lại chẩn đoán đầy đủ cho người dùng hoặc tác nhân người dùng để tác nhân người dùng có thể hiển thị thông báo để người dùng ngừng thử lại và chỉ hỗ trợ liên hệ. Mặt khác, nếu API này chỉ dành cho các hệ thống,


Tất cả 404 thực sự nói là "thứ đó không có ở đây và tôi không biết nó ở đâu". 3xx và 5xx là ok để thử lại. Nhưng 4xx nói, "truy vấn hiện tại của bạn không đủ để tôi tìm thấy thuốc chống nôn cho bạn. Làm ơn đi đi."

Tôi thích khả năng phân biệt giữa URL KHÔNG TÌM KIẾM và Tài nguyên KHÔNG TÌM KIẾM ... Vì vậy, Điểm cuối dịch vụ đã hoạt động và chạy 200, tuy nhiên tài nguyên được yêu cầu KHÔNG phải là FOUND 404 (Phần phản hồi).
Nước chanh
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.