Скажем, у меня есть конечная точка REST, которая принимает целое число в качестве параметра:
/makeWaffles?numberOfWaffles=3
В этом случае я хочу, чтобы число было положительным, потому что я не могу сделать отрицательное число вафель (а запрос 0 вафель - пустая трата времени). Поэтому я хочу отклонить любой запрос, который не содержит положительного целого числа. Я также хочу отклонить запрос, который превышает некоторое максимальное целое число (скажем, пока это MAX_INTEGER).
Если кто-то запрашивает не положительное число вафель, должен ли я вернуть статус HTTP 400 (Bad Request)? Сначала я подумал: да, это неправильный номер для выполнения запроса. Тем не менее, RFC не упоминает бизнес-правила в качестве причины, чтобы бросить его:
Код состояния 400 (неверный запрос) указывает на то, что сервер не может или не будет обрабатывать запрос из-за чего-то, что воспринимается как ошибка клиента (например, синтаксис искаженного запроса, кадрирование неверного сообщения запроса или обманчивая маршрутизация запроса).
Бизнес-правило не подпадает ни под один из этих трех примеров. Это синтаксически правильно, правильно оформлено, и это не обманчивая маршрутизация запросов.
Так должен ли я возвращать статус HTTP 400 (неверный запрос), если параметр синтаксически правильный, но нарушает бизнес-правило? Или есть более подходящий статус для возвращения?
источник
Ответы:
Это большой вопрос, и он все еще очень актуален, учитывая исторический контекст (и, казалось бы, противоречивые определения) кодов возврата HTTP. Даже среди ответов на этот вопрос есть противоречивые определения. Это можно выяснить, двигаясь в хронологическом порядке.
RFC 2616 (июнь 1999 г.)
Что касается данного RFC, этот код состояния применяется только к синтаксически неверным запросам. Был пробел в кодах статуса для семантической проверки. Таким образом, когда появился RFC 4918, появился новый код.
RFC 4918 (июнь 2007 г.)
422 Unprocessable Entity был создан, чтобы заполнить пробел семантической проверки в исходной спецификации кодов состояния 4xx. Тем не менее, в 2014 году появился еще один соответствующий RFC, который обобщил 400, чтобы больше не относиться к синтаксису .
RFC 7231 (июнь 2014 г., явно устарел RFC 2616)
Обратите внимание, что в описании 422 говорится, что причина 400 неуместна в том, что 400 (начиная с RFC 2616) следует возвращать только для синтаксиса неверного запроса. Однако, начиная с RFC 7231, строгое определение синтаксической ошибки больше не относится к 400 .
Возвращаясь к рассматриваемому вопросу: хотя с технической точки зрения 422 технически более специфичен, с учетом этого контекста я мог видеть, что 400 или 422 используются для семантической проверки параметров API. Я не решаюсь использовать 422 в своих собственных API, потому что определение 422 технически устарело на данный момент (хотя я не знаю, признано ли оно где-либо официально). Статья, на которую ссылается в ответе Фрэн, которая поощряет использование 422, была написана в 2012 году, за два года до того, как RFC 7231 разъяснил HTTP 400. Просто убедитесь, что стандартизировали один или другой.
источник
Я прочитал первый ответ и на самом деле не согласился с ним, потому что, по крайней мере в моем чтении, неверный запрос (400) означает: «Я даже не могу обработать ваш запрос, потому что что-то в корне неправильно». И я нашел этот пост, который оправдывает возвращение 422.
от IETF
422 Unprocessable Entity (WebDAV; RFC 4918) Запрос был правильно сформирован, но не мог быть выполнен из-за семантических ошибок
Это кажется более подходящим ответом, поскольку ваш запрос правильно сформирован, но не соответствует правилам проверки.
источник
Нет, не стоит. HTTP-коды предназначены для уровня HTTP вашего приложения. Бизнес-правила - это совершенно другой уровень и зависят от приложения, поэтому вам нужно придумать свой собственный «протокол».
Представьте, что произошел апокалипсис, и вы должны переключиться с протокола HTTP на использование голубей. У голубей нет никаких кодов возврата, поэтому вам нужно будет изменить свой бизнес-уровень, чтобы приспособиться к этому. Но ваш бизнес на самом деле не изменился, поэтому вам не нужно менять бизнес-уровень. Это показывает тесную связь между этими двумя уровнями (транспорт и бизнес).
Вернемся к вопросу: что вы должны сделать, это вернуть «200 OK» с телом, описывающим, что произошло с запросом. В спецификации четко сказано так:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1 .
Успешен ли ваш HTTP-запрос? Да, веб-сервер знает, что делать с этим запросом (например, передать его серверной части вашего приложения). Затем веб-сервер передает этот запрос серверной части вашего приложения, которая принимает POST-данные, обрабатывает их (проверяет их в вашем случае) и возвращает нормальный ответ (в теле HTTP-ответа) клиентской части вашего приложения. , Этот ответ от серверной части приложения может быть либо «Отлично, отправленные вами данные верны», либо «Извините, отправленные вами данные недействительны». И ваша клиентская часть приложения должна понять, что означает ответ.
PS: «400 Bad Request» означает, что веб-сервер не понял, что вы хотите от него. Это означает, что ваша серверная часть вашего приложения даже не получила запрос. Или, по крайней мере, это означает, что это означает :-)
РЕДАКТИРОВАТЬ : Я только что понял, что вы делаете запрос GET, а не POST. Это плохая идея, потому что GET не должен изменять состояние приложения. GET должен просто получать данные с сервера. Но в своем запросе вы фактически меняете состояние приложения, поэтому вам действительно следует использовать POST.
источник
Да, входные данные, которые не соответствуют подразумеваемому контракту конечной точки, являются «чем-то, что воспринимается как ошибка клиента», и должны возвращать 400.
Исключением является случай, когда бизнес-правило связано с безопасностью (тогда
401 Unauthorized
или403 Forbidden
будет лучше). В качестве альтернативы, если отправка 400 будет утечка информации о существовании чего-то, и тогда404 Not Found
может быть более подходящим.источник
Не уверен, что все согласятся, но мы используем 409 - Конфликт. Многие утверждают, что 409 - это скорее конфликт с состоянием системы, но мы согласились с интерпретацией, что конфликт значений данных, выходящий за пределы допустимого диапазона, может быть исправлен запрашивающей стороной и допустимым использованием 409. 422 Я думаю, что это было бы разумно в качестве запроса правильно сформирован, но не может быть обработан в соответствии с запросом. Однако я полагаю, что если вы не хотите реализовывать множество ответов, просто дать 400 все равно приемлемо.
источник