Каким должен быть код состояния http для ошибки «Служба недоступна в вашем регионе»?

51

Наш сервис сейчас в 5 городах. Если кто-то пытается вызвать наш сервис API из любого другого города, мы хотим выбросить эту ошибку Service not available in your area.

Вопрос в том, какой код http будет подходящим для этой ошибки?

  • сервис 503 недоступен
  • 403: запрещено

или что-то другое?

Shaharyar
источник
52
«Если кто-то пытается вызвать наш сервисный API из любого другого города», обратите внимание, что геолокация IP-адресов очень часто бывает неправильной; если вы запрещаете любому пользователю, чей IP-адрес привязан к другому городу, вы, скорее всего, будете блокировать законных пользователей.
Питер Грин
43
Разве мне не разрешено подвезти своего ребенка, который находится в другом городе и должен приехать в аэропорт, чтобы навестить меня?
Дауд говорит восстановить Монику
29
Хотя HTTP 451 (RFC 7725) и не является ответом на этот вопрос, он может пригодиться будущим читателям, которые найдут этот вопрос. Его главная цель - указать, что контент недоступен из-за юридического запроса, действия или ограничения (авторское право, постановление суда и т. Д.)
Tyzoid
34
Если нет ничего плохого в сетевом соединении, аутентификации, внутренних ошибках в приложении и синтаксически правильном вводе, сообщения об ошибке не должно быть. С «мы не предлагаем наши услуги в этой области» вы оставили технологические проблемы и ушли в бизнес-проблемы, поэтому я не уверен, что ошибка HTTP будет уместной. Я думаю, что вы должны дать 200 и (или 302 и перенаправить) соответствующее сообщение о том, "извините, наш сервис недоступен в вашем регионе - пока. Но мы расширяемся - проверьте в конце 2019 года!" или что бы ни придумал отдел маркетинга.
Иваниван
7
Из вопроса неясно, хотите ли вы заблокировать весь доступ к API на основе местоположения клиентского компьютера (географический IP?) Или если вы запрашиваете код ответа для определенного неудачного запроса API (например, book? Address = 123_example_st_london) , Является ли местоположение частью ввода, или у вас есть другое местоположение клиента?
Бен

Ответы:

101

Любой код ошибки HTTP не подходит. Там нет ошибок или проблем любого рода с точки зрения HTTP, поэтому он должен быть что-то в диапазоне 200. Вы вежливо сообщаете некоторым своим пользователям, что они не будут обслуживаться, отправляя обратно документ, который сообщает им об этом. И все это хорошо.

Пользователь не сможет использовать ваше приложение . Это сознательное решение, принятое вашей бизнес-логикой, а не неудача. На уровне HTTP все честно.

редактировать

Похоже, то, на что мы смотрим, это столкновение старой школы с новой. Когда разрабатывался HTTP, не было веб-сервисов, не было ни SOAP, ни JSON, ни REST-принципов. В качестве протокола выше TCP это уже рассматривалось (близко к) уровню приложения, и были определены многие коды состояния высокого уровня. Когда сеть начала использоваться для более богатых, высокоуровневых сервисов и общих средств транспортировки «конвертов», разработчики предпочитали использовать HTTP вместо определения более нового и более чистого протокола только потому, что HTTP был повсеместным.

Таким образом, в контексте современных веб-сервисов HTTP действительно немногим больше, чем тупой транспортный уровень, и большинство его кодов можно считать неприменимыми или устаревшими. Просто выберите один, потому что он приближается к состоянию вашего приложения и находится в этом списке, что когда-то означало, что что-то может показаться безопасным, но я думаю, что это пошло бы неправильно. Вы не хотите, чтобы HTTP играл эту регулирующую роль в контексте веб-службы.

Мартин Маат
источник
56
По этой логике любая ошибка приложения должна быть возвращена как 200. И все запросы должны быть POST, даже удаления. Этот подход рассматривает HTTP как непрозрачный транспортный протокол - как TCP. Это не то, как обычно обрабатывают API веб-сервисов - они пытаются использовать семантику HTTP в качестве стандартного языка для API. Почему бы не вернуть 401 для Несанкционированного, а не вернуть 200 с нестандартным нестандартным кодом ошибки?
Авнер Шахар-Каштан
31
По этой логике ни одно приложение не должно возвращать никакого ответа в диапазоне 400. Это именно то условие, для которого предназначен диапазон 400 ответов. Кроме того, применимо ли ваше первое предложение ко всем будущим ответам, а также к тем, которые были опубликованы раньше ваших?
Дауд говорит восстановить Монику
31
Я должен согласиться с тем, что это всего лишь простые 200. Пользователь задал вопрос, мы поняли его, мы знаем правильный ответ, и мы предоставили ему ответ (который, как оказалось, «Нет»). Все хорошо в земле HTTP.
Ли Даниэль Крокер
8
Хе-хе ... быстрое путешествие от "это на самом деле не ошибка" к "так, ты говоришь, что ничто не является ошибкой?"
svidgen
28
Этот. «Вы пытались получить доступ к URL-адресу, который не существует» сильно отличается от «Наша компания не работает в вашем регионе». Только один имеет отношение к HTTP.
CJ Деннис
87

5xxошибки - ошибки сервера - на сервере что-то пошло не так. В частности, 503 указывает, что:

сервер в настоящее время не может обработать запрос из-за временной перегрузки или планового обслуживания

4xxошибки - это ошибки клиента - клиент делает запрос, который сервер не может или не хочет выполнить. В частности, 403 указывает, что

сервер понял запрос, но отказывается его авторизовать. Сервер, который желает обнародовать, почему запрос был запрещен, может описать эту причину в полезной нагрузке ответа (если есть). [..] Однако запрос может быть запрещен по причинам, не связанным с учетными данными.

Я бы сказал, что 503это явно неправильно, потому что это не временная проблема - вы не поддерживаете запросы в этой области, точка. Можно утверждать, что вы в конечном итоге надеетесь поддержать область, но цель кода - включить заголовок, указывающий, когда клиент может повторить попытку. «Через 6 месяцев» не придерживается намерения.

403 это лучший выбор, потому что ваш сервис просто запрещает запросы из определенных регионов.

Эрик Стейн
источник
403 для случаев, когда доступ запрещен, и клиент ничего не может с этим поделать. Но в этом случае клиент может (сесть в машину с ноутбуком или телефоном), поэтому 403 неуместно.
gnasher729
2
@ gnasher729 Ошибки 4xx связаны с тем, что клиент мог бы исправить, включая 403. Спецификация (связанная) специально указывает, что клиент может повторить попытку с другими учетными данными (если предположить, что проблема была в учетных данных).
jaxad0127
22
@ gnasher729 403 не означает, что человек ничего не может с этим поделать. Это означает, что браузер не может ничего с этим поделать. Человек всегда может сделать сброс пароля, поговорить с администратором или в этом случае переехать в другой город.
Slebetman
1
@ gnasher729 Клиент не пользователь.
Капитан Мэн
10
5xx = Упс, плохо, держись, пока мы исправим проблему. 4xx = Извините, но в соответствии с политикой мы не можем удовлетворить ваш запрос в настоящее время. Вот почему ....
candied_orange
46

Ни один из тех.

Если ваш API хорошо спроектирован, в URL входит название города, например

http://example.com/API/Vienna/HailRide

или же

http://example.com/API/HailRide?city=Vienna

поскольку геолокация IP ненадежна, ваши пользователи могут использовать VPN, ваши пользователи могут захотеть подвезти кого-то еще и т. д. Ответственность за выбор города в зависимости от местоположения пользователя лежит на клиенте API . Обычно клиент имеет гораздо лучшие ресурсы для определения местоположения пользователя в любом случае (например, служба определения местоположения мобильного устройства).

Как только вы это сделаете, правильный ответ

http://example.com/API/SomeUnsupportedCity/HailRide

или же

http://example.com/API/HailRide?city=SomeUnsupportedCity

становится очевидным: 404 Not Found : не существует ресурса для того, чтобы приветствовать поездку в SomeUnsupportedCity.

Heinzi
источник
6
Это должен быть принятый ответ: дизайн API - это не только соответствие старым числовым кодам, а сценарий с vpn и т. Д. Вполне реалистичен.
Эдоардо
10
Я должен не согласиться с этим. Включение названия города в URL может привести к возникновению всевозможных проблем в будущем, потому что это заставляет клиента определять название города на основе местоположения, и вам может не понравиться результат. Например, вы в Лос-Анджелесе или в Беверли-Хиллз? Лондон или Вестминстер? Что произойдет, если клиент думает, что он в Ричардсоне, но вы хотите, чтобы API обслуживал всю область Далласа? Было бы лучше, если бы клиент просто указывал места посадки / высадки; сервер может определить, находятся ли они в зоне обслуживания, и ответить соответствующим образом.
Зак Липтон
11
@ZachLipton Я почти уверен, что названия городов были только примером, это зависит от реальных бизнес-правил ОП, как они определяют «город» или «местоположение». Это также может быть координата.
Берги
1
@ZachLipton нет, дело в том, что служба не использует IP-адрес клиента, чтобы понять местоположение, это просто неправильно
Эдоардо
3
@eddyce Я согласен, что использование клиентского IP - плохая идея по многим причинам. Я говорю, что / API / Vienna / HailRide также подвержен проблемам, поскольку требует, чтобы клиент преобразовывал местоположения в названия городов, а это не сопоставление 1: 1, соответствующее областям, в которых компания работает.
Зак Липтон
26

Это похоже на вопрос круглой дыры / квадратного колышка. Почему ваш единственный ответ должен быть HTTP-кодом? Коды ошибок HTTP не могут охватывать все случаи использования.

Все ваши вызовы API должны иметь дополнительный обмен сообщениями - например, небольшое сообщение об ошибке JSON. Дайте им 403 (потому что, на самом деле, у них нет разрешения использовать API с учетом местоположения) и верните дополнительный бит информации, как вы предлагаете.

Если вы этого не сделаете, в следующий раз вы спросите, какой код ошибки HTTP нужно вернуть, когда пользователь запросил внедорожник, но доступен только Prius.

stdunbar
источник
5
+1 за ваше последнее предложение. Подводит итоги приятно.
LoztInSpace
1
Ну, это вполне очевидно, что 3xx должен быть редиректом. ;)
Настоящее имя отредактировано
В последнем случае, вероятно, требуется какой-то ответ 4xx: пользователь сделал запрос, который сервер не может выполнить. Было бы 400, если бы выбор был неким неверным вводом или 404, если само местоположение просто не существует. Хотя может быть и 200, если это критерии поиска и просто нет совпадений.
jpmc26
11

Некоторые имеют смысл.

403 Запрещено по причинам, которые Эрик Стейн упоминает в своем ответе . Вы можете использовать различную информацию, предоставленную запросом, чтобы определить, где находится клиент и кто является клиентом, и на основании этого запроса сервер не может или не желает отвечать.

Тем не менее, я бы также выдвинул 451 «Недоступно по юридическим причинам» в качестве возможного статуса возврата в некоторых случаях. Этот статус предполагает, что вы включите (в заголовки) ссылку на соответствующее законодательство. Это специально для случаев, когда клиент не имеет права доступа к вашим ресурсам, и не существует более общего случая, когда клиент находится в неподдерживаемом регионе или области.

Я бы избежал серии статусов 5xx - они часто указывают на технические проблемы на стороне сервера. Это не похоже на случай здесь.

Томас Оуэнс
источник
Вероятно, причина в этом случае заключается в том, что нет смысла рассказывать пользователю об автомобилях, которых нет в их городе. Так что дело не в 451
макс630
4
@ max630 Вы не можете предположить это из вопроса. 403 Forbidden - это, скорее всего, правильный выбор. Однако, если существуют юридические ограничения на услугу, вместо этого можно использовать более конкретный 451. 451 часто рассматривается как более конкретная версия 403 для очень особых случаев использования, поэтому имеет смысл поднять ее.
Томас Оуэнс
8
@ max630 - вполне возможно, что здесь подходит 451. Во многих юрисдикциях требуется, чтобы операторы этого вида услуг были зарегистрированы в региональных органах власти до их предоставления. На самом деле им может быть юридически запрещено обрабатывать определенные запросы, если они исходят из-за пределов территории.
Жюль
5

Если ограничение связано с юридическими причинами, то соответствующий код ошибки HTTP - HTTP 451 «Недоступно по юридическим причинам».

Это обычно используется в случае материала, который был отозван из-за действий DMCA или судебных исков из-за кампаний преследования или тому подобного, но дух и буква определения ответа гласят :

В этом документе указывается код состояния протокола передачи гипертекста (HTTP), который используется, когда доступ к ресурсам запрещен вследствие юридических требований.

Сам код является ссылкой на Фаренгейт 451 Рэй Брэдбери.

пушистый
источник
3

Люди часто забывают, что коды состояния HTTP являются расширяемыми.

Коды состояния HTTP расширяемы. Приложения HTTP не обязаны понимать значение всех зарегистрированных кодов состояния, хотя такое понимание, очевидно, желательно. Однако приложения ДОЛЖНЫ понимать класс любого кода состояния, как указано первой цифрой, и обрабатывать любой нераспознанный ответ как эквивалентный коду состояния x00 этого класса, за исключением того, что нераспознанный ответ НЕ ДОЛЖЕН кэшироваться. Например, если клиент получил нераспознанный код состояния 431, он может с уверенностью предположить, что с его запросом что-то не так, и обработать ответ, как если бы он получил код состояния 400. В таких случаях пользовательские агенты ДОЛЖНЫ представить пользователю объект, возвращенный с ответом,

https://tools.ietf.org/html/rfc2616#section-6.1.1

Вы всегда можете просто создать свой собственный код состояния в диапазоне 400 для использования вашим API и клиентским приложением.

Резиновая утка
источник
Хм ... может и не понадобиться, если в запрос включен Expect token;city="Albequerque"заголовок. Тогда самый подходящий ответ будет 417, ожидание не удалось. tools.ietf.org/html/rfc2616#section-10.4.18 Предполагая, конечно, что это для веб-службы.
Берин Лорич
Может быть, нет необходимости @BerinLoritsch, но вместо того, чтобы пытаться принудительно вписать ситуацию в существующий код, может быть лучше просто добавить и использовать пользовательский.
RubberDuck
0

Сначала я подумал, что 503, потому что описание «служба недоступна», кажется, соответствует проблеме, но, глядя на определения , 503 действительно относится к недоступности сервера. Затем, подумав больше, вы говорите клиенту, что есть проблема с запросом, а не проблема со стороны сервера.

403 ближе, потому что вы говорите пользователю, что получили сообщение и понимаете его, но сервер не желает его удовлетворить. Это может сбивать с толку, поэтому для описания сценария можно добавить текстовое объяснение. Согласно RFC, 404 также является действительной заменой этого кода.

Если кто-то не придумал новый код для этого, 403 или 404 кажутся самыми близкими.

JimmyJames
источник
Определенно не код 5xx, потому что это подразумевает, что попытка точно такого же запроса позже может быть успешной. Код 4xx определенно говорит клиенту не пытаться снова, не изменяя хотя бы часть запроса (в данном случае, поле «расположение службы»).
Тоби Спейт
0

Вам следует сопоставить описание ошибки с кодом, который вы даете:

  • если вы говорите, Service not available in your area.вы должны дать, 404потому что вы утверждаете, что услуга недоступна .

  • если вы говорите, You are not authorized for this service in your area.вы должны дать, 403потому что вы утверждаете, что звонящий не авторизован .

Я бы пошел на второй.

Эдоардо
источник
6
404 не о доступности , это о существовании . Просто потому, что в некоторых случаях услуга недоступна, вы не должны предоставлять ответ 404, если вы не хотите, чтобы люди поверили, что его вообще не существует. Ответ 404 будет бессмысленным для этой ситуации.
Жюль
@jules Согласно спецификации для 403 (которая может быть устаревшей): «Если сервер не хочет предоставлять эту информацию клиенту, вместо этого можно использовать код состояния 404 (Не найдено) ». Таким образом, если 403 в порядке, то 404 также будет, но не обязательно по указанной причине.
JimmyJames
@JimmyJames - да, это в пределах спецификации, но это действительно плохая идея, потому что это делает проблемы отладки чрезвычайно трудными. Не то, что вы хотите в API.
Жюль
3
@Jules Сервис не существует в некоторых областях. Как и в моем городе есть много небольших магазинов, поэтому, спрашивая их адрес в другом городе, правильный ответ «не существует».
Энди
Гм, говорить о «существовании» о пути URL-адреса службы - это наименее - философский, для ясности, как только вы опубликуете путь, вы должны дать ответ, 403 - это путь в этом случае с неким словесным описанием ситуация.
Эдоардо
0

Существует текущий интернет-проект (срок действия которого истекает 31 декабря 2018 года), в котором предлагаются поправки к статусу HTTP 451, недоступному по юридическим причинам . В проекте предлагается, чтобы ответ 451 содержал geo-scope-blockзаголовок, который должен «соответствовать разделенному запятыми списку кодов стран альфа-2, определенных в [ISO.3166-1]». Однако в проекте также указывается, что код 451 не должен использоваться «оператором для запрета доступа к ресурсу на основе политики, указанной оператором (в отличие от юридического требования, предъявляемого к оператору)».

Таким образом, если у вас нет законного требования на геоблок, то 451 - неправильный код. Какой правильный код тогда? Ну, многие другие ответы уже предложили 403 Запрещено , но все они, похоже, «основаны на мнении», поэтому давайте посмотрим, что делают другие:

Таким образом, не существует единого универсального решения, вам просто нужно будет выбрать то, которое, по вашему мнению, лучше всего подходит для вашей ситуации. Но какой бы вы ни выбрали, обязательно объясните фактическую проблему в теле ответа .

Я бы сказал, что нет ничего плохого в том, чтобы просто указать собственный код состояния HTTP, как уже ответил RubberDuck . Пользовательский код состояния в диапазоне 400 может быть даже довольно хорошим вызовом, потому что он определенно привлечет внимание разработчиков, если они увидят что-то вроде «HTTP status 499». «403» слишком легко передать как « ОК, поэтому я неправильно ввел пароль, давайте попробуем что-то другое », и это приводит к потере часов.

ZeroOne
источник