статус код 200 что это
200 — это хорошо или это плохо?
В этой трехминутной статье я хочу затронуть наболевшую тему.
Речь пойдет о статус коде HTTP 200 и ошибках в ответе.
Нормально ли возвращать такой код, если возникла ошибка?
Нет? Да? Ну-ка давайте разберемся.
Случай 1. HTTP 200 и batch операция
Допустим отправляется один запрос. Запрос выполняется успешно. Возвращаем код 200. Ответ не содержит информации об ошибке. С этим случаем всё предельно просто и понятно. А что делать если требуется выполнить batch операцию?
Например, мы работаем с сервером изображений. Предоставляемый API позволяет загрузить за один запрос сразу несколько файлов.
Запрос выглядит примерно так:
Предположим, по какой-то причине (например, кончилось место на сервере) видео загрузить не удалось. Что бы вы вернули в таком случае? 2xx или 4xx или 5xx? Сервер, отвечает примерно вот так:
Некоторые сервисы (и вполне известные) действуют также. Отвечают 200. А в ответе возвращают список команд, которые выполнить не получилось.
Случай 2. HTTP 200 и ошибки в ответе
Пришёл запрос. Запрос зафейлился. Например, мы забыли указать какое-то поле. Или дату отправили не в миллисекундах, а как строку. Тут-то точно не надо возвращать 200! Но увы и нет.
Где-то на просторах интернета я встречал проекты на github и bitbucket, которые специально предназначены для таких вот случаев. В них просто вшиты возможные варианты и шаблоны. Можно их достаточно легко встроить в свой проект и как бы быть готовым к разного рода «падениям» запросов. Но есть одно но.
В такие моменты твой код становится уродливым. Ты ему говоришь:
— Cлушай, у нас тут есть один внешний API. Он в целом нормальный. Только надо внимательно смотреть что в ответе приходит. Если там ответ содержит поле «error», то значит запрос сломался.
— Но ведь для этого же есть 4xx и 5xx! Да кто вообще так делает?!
— Тише-тише. Не надо так громко. Он может услышать. Пожалуйста, будь добрее к нему. И просто смотри не только на статус код, но и на ответ, пожалуйста.
— Ладно…
HTTP 200 — это просто статус
Ну 200 и 200. Ну не запилили. Или не успели. Или вообще не будут. Ну и что?! Написал json парсер и всё!
Как бы да, но я хочу знать почему. Забыли? Забили? Не успели? Не знали?
Возможно я что-то упускаю. Или не знаю. Хочу ваше мнение. Срочно. Всем добра и выходных на выходных.
Коды ответа HTTP
Код ответа (состояния) HTTP показывает, был ли успешно выполнен определённый HTTP запрос. Коды сгруппированы в 5 классов:
Если вы получили код ответа (состояния), которого нет в данном списке, в таком случае он является не стандартизированным кодом ответа (состояния), вероятней всего он кастомный сервера.
Следующая таблица содержит список всех кодов и их значения:
Этот ответ отсылается, когда веб сервер после выполнения server-driven content negotiation, не нашёл контента, отвечающего критериям, полученным из user agent.
Этот ответ отсылается, когда запрос конфликтует с текущим состоянием сервера.
Этот ответ отсылается, когда запрашиваемый контент удалён с сервера.
Размер запроса превышает лимит, объявленный сервером. Сервер может закрыть соединение, вернув заголовок Retry-After
Коды ответов сервера 2ХХ, 3ХХ, 4ХХ, 5ХХ
Какие бывают http ответы сервера (сайта, страницы)?
Коды ответа http сервера (англ. HTTP status code) являются частью первой строки ответа сервера. Он представляет собой целое трехзначное число, первая цифра которого указывает на класс состояния. Вместе с кодом ответа выдается короткая англоязычная подсказка. Продвижение сайтов в сети интернет невозможно без знания ответов сервера.
Пример:
404 Not found
Дальнейшие действия зависят именно от того, какой код ответа дал сервер или страница. Ввиду того что набор кодов является стандартным для всех сайтов/страниц/серверов, действия при выдаче того или иного кода тоже будут стандартными.
На сегодняшний день выделено 5 основных классов кода ответа:
1xx: Informational (рус. Информационный) — запрос правильно воспринят, но его обработка не завершена.
2xx: Success (рус. Успешно) — запрос правильно воспринят и успешно обработан.
3xx: Redirection (рус. Перенаправление) — коды переадресации на другие страницы.
4xx: Client Error (рус. Ошибка клиента) — ошибка со стороны клиента.
5xx: Server Error (рус. Ошибка сервера) — ошибка со стороны сервера.
А теперь давайте по отдельности разберем некоторые коды состояния IANA.
Ответ сервера 1XX
100 Continue Server Code
100 Continue сообщает, что связь с сервером уже установлена, сервер принял корректный запрос и теперь ведется обмен данными между сервером и клиентом. Данный код является временным, т.е. за ним всегда следует другой. Код 100 является внутренним и не относится к ошибочным. Т.е. «дверь открыта, читай что нужно, как закончишь – закрой». Код 100 может и не генерироваться, если пользователь уже получил часть данных от сервера.
101 Switching Protocols
Данный код так же не является ошибочным. Генерируется при переключении с одного протокола на другой. Например, при запросе переключения со старой версии HTTP на более новую.
Это, один из самых простых серверных кодов. Он означает, что со стороны пользователя поступил запрос на переключение типа протокола, используемого на веб-сервере, и сервер дал согласие на это.
102 Processing
В каком-то смысле это аналог кода 100. Генерируется в том случае, когда обработка запроса может занять много времени. Для этих целей таймер ожидания сбрасывается и ожидание дальнейших команд происходит в обычном режиме. Так же не является кодом ошибки.
Ответ сервера 200 ОК
По праву занимает самое первое место по важности и популярности, т.к. именно его отдает сервер в случае успешной и правильной обработки запроса пользователя.
Ответ сервера 301
Ответ сервера 302
Данный код сообщает о том, что расположение запрашиваемой страницы временно изменено. Также должна быть предоставлена информация о новом местоположении запрашиваемого документа. Данный код изначально использовался в качестве основного способа перенаправления.
Ответ сервера 404
Вот уж что-что, а ошибку ответа сервера 404 не видели только те, кто еще не родился и те, кто умер до создания интернета. Данный код сообщает о том, что запрашиваемый документ по каким-то причинам на сайте отсутствует. Код ошибки ответа сервера 404 должен отдаваться только в том случае, если по указанному пользователем адресу документа никогда не было. Если документ ранее был доступен по этому адресу, а потом его удалили с сайта, то сервер должен отдавать код 410, а не 404.
Фейковые страницы 404
Большинство вебмастеров не обращает на 404-тые страницы никакого внимания, однако, это может серьезно навредить ранжированию сайта. Парадокс, но страница с сообщением 404 File Not Found далеко не всегда отдает код 404. Такие страницы принято называть «Soft 404». Причины возникновения просты – по каким-то причинам страница отдает код, отличный от 404 и 410 – например, 200. Такое вполне возможно, если страница уже создана, но контента на ней пока нет.
Ответ сервера 500
Все коды серии 5хх свидетельствуют о том, что сервер не в состоянии завершить обработку запроса. Вместе с кодом должно появляться и поясняющая подсказка (с причиной) на английском языке.
500 Internal Server Error
Код 500 отдается в случае любой внутренней ошибки сервера, за исключением остальных ошибок 5хх класса. Такая ошибка может быть отдана в том случае, когда ссылка генерируется на сервере непосредственно в момент запроса. Простейший пример – внутренний поиск по сайту: физически никакого документа по запрашиваемой ссылке нет.
Ответ сервера 502
Код 502 может отображаться в тех случаях, когда сервер играет роль шлюза или прокси, но при этом не удалось «найти общий язык» между ним и вышестоящим сервером, т.е., по сути, это просто ошибка обмена данных.
Ответ сервера 550
Для проверки необходимо перейти по ссылке (https://www.reg.ru/nettools/dig), затем прописать имя проверяемого домена, а в списке выбрать «MX». Теперь нажимаем Проверить:
На выходе будет представлена таблица.
Необходимо убедиться, что в ней прописаны необходимые записи для работы вашей почты:
Почта
MX-записи
Почта REG.RU на хостинге
mx1.hosting.reg.ru и mx2.hosting.reg.ru
Mail.Ru для бизнеса
Расширенная защита от спама
mxs1.reg.ru и mxs2.reg.ru
Почта REG.RU на VPS
Как получить коды ответа сервера (страницы) через Яндекс
Шаг 1. Проверяем код ответа сервера на страницу сайта, которая должна быть в поиске.
Открываем любую страницу Вашего сайта, находящуюся в поисковой выдаче Яндекса, затем из адресной строки копируем ее URL-адрес.
Теперь переходим в сервис Яндекса (http://webmaster.yandex.ru/server-response.xml), с помощью которого можно посмотреть на сайт глазами робота и проверить скорость ответа сервера в Яндекс панели.
Просто вставляем url-адрес интересующей нас страницы в текстовое поле и нажимаем на кнопку «Проверить». В данном случае мы получили код 200 ОК, свидетельствующий о нормальной работе страницы.
Шаг 2. Проверяем ответ сервера на заведомо несуществующую страницу.
В том же сервисе вводим имя_домена/какая-то_крокозябра
В данном случае мы получили ответ 301 Moved Permanently. Это говорит о том, что адрес страницы указан неверно и происходит переадресация на правильный адрес.
Как еще узнать коды ответа сервера (сайта)?
Mainspy
В качестве альтернативы можно пробить код ответа с помощью сервиса http://mainspy.ru. Работает аналогично сервису Яндекса: вставляем интересующий URL и жмем «Проверить». Код ответа в данном случае находится в самой первой строке:
Bertal
Bertal, в отличие от Mainspy, позволяет взглянуть на страницу не только глазами Яндекс-бота, но и глазами поисковых роботов Bing и Google, а в качестве бонуса – может эмулировать популярные браузеры. Для удобства взглянем на те же страницы глазами GoogleBot. В данном случае код ответа подсвечен зеленым.
Массовая проверка ответов сервера (сайта) онлайн
Массовая проверка кодов ответа может пригодиться для поиска неработающих сайтов, на которых были куплены ссылки (через биржи или напрямую – неважно).
Urlitor
Urlitor – еще один сервис, для массовой проверки кодов ответа. Сервис хорош тем, что результаты проверки сводятся в таблицу для облегчения восприятия. К слову – ссылки в таблице кликабельны.
Как проверить скорость (время) ответа сервера сайта?
Сколько таких сервисов уже развелось – не пересчитать. Рассмотрим некоторые из них.
Pingdom
Это англоязычный инструмент, анализирующий скорость по всем параметрам. С его помощью можно узнать скорость в секундах, сколько весит тестируемая страница, а также получить оценку и рекомендации для ее улучшения. Преимущество данного сервиса в том, что анализируется каждый отдельный элемент. Такой анализ позволяет выяснить, что именно затормаживает загрузку отдельно взятой страницы и/или сайта в целом.
Which Loads Faster
Основная фишка данного сервиса в том, что анализируется время загрузки одновременно двух ресурсов. Это позволяет узнать, какой из двух ресурсов работает быстрее. Единственный минус – при разных подключениях и в разных браузерах результат может отличаться.
Google PageSpeed Insights
Google PageSpeed Insights так же является одним из самых мощных инструментов для измерения скорости работы мобильной и десктопной версии. Оценка производится по 100-бальной шкале. 85 баллов и более – это хороший показатель. Плюс бонусом он выдает рекомендации по улучшению.
Долгий ответ сервера
Ответ, длительность которого составляет больше, чем полсекунды, принято называть «долгим». Поэтому, при длительной загрузке сайте вы можете видеть сообщение в браузере «превышено время ожидания ответа от сервера». Причин долгого ответа может быть уйма:
— сложная логика предоставления данных
— сервер не успевает своевременно обрабатывать поступающие запросы из-за их большого количества
— сами запросы (либо сложные, либо неоптимизированные, либо и то и другое)
— запросы к большому количеству внешних ресурсов
— большое количество исполняемых файлов
— сам веб-сервер долго обрабатывает запрос.
Самые «больные» места производительности сервера:
Используемый веб-сервер (Apache, IIS).
Ряд веб-серверов даже при выдаче статических файлов могут создавать задержки, т.к. они на архитектурном уровне не предназначены для обработки большого количества запросов и из-за этого может быть сообщения что превышено время ожидания ответа от сервера. Поэтому для нормальной работы веб-сервера имеет смысл использовать nginx (причем в связке с Apache, php-fpm, а также остальными серверами приложений для обработки серверных вычислений).
Использование OpCache.
Сократите время ответа сервера путем кэширования исполняемого кода (скриптов сайта) – оно позволяет воспользоваться уже готовым результатом вместо того, чтоб каждый раз переводить PHP-инструкции в бинарный код. Но это кэширование с кэшированием результатов выполнения PHP-скриптов не имеет вообще ничего общего.
Запросы к базе данных.
Сложная логика обработки данных.
Третий шаг – упрощение серверной логики. По сути, это просто устранение ненужных операций и профилирование времени выполнения серверных скриптов.
Обращение к сторонним сервисам.
Прописанные в коде серверных скриптов запросы к сторонним сервисам – это «обычная история», способная преподнести множество сюрпризов, поскольку производительность сервисов, откуда запрашиваются данные, практически никогда и никем не проверяется. А ведь время ответа стороннего сервиса напрямую влияет на время ответа сервера. Поэтому лучше всего в серверных запросах использовать только внутренние источники, которые в любой момент можно проконтролировать на качество производительности, либо в отложенном режиме запросить данные на клиентской.
Почему скорость ответа веб сервера влияет на продвижение.
Во-первых, потому что скорость загрузки является одним из факторов ранжирования (хоть и не решающим). Google открыто заявляет, что по скорости показа страниц ранжируется менее 1% сайтов. НО…
Превышено время ожидания ответа от сервера.
Для начала важно понимать причину возникновения сбоя. Т.е. пользователь вводит адрес, а браузер в этот момент отправляет группу запросов, а также включает обратный секундомер на каждый из них. Если по истечении заданного времени браузер не получает ответ на свой запрос, то пользователь увидит вот такую неприятную картинку.
Основных же причин сбоя может несколько:
Проблемы с подключением к интернету со стороны пользователя;
Что делать для решения?
Если сбой единичен – перезагружаем страницу с помощью комбинации Ctrl+F5. Возможно, потребуется перезагрузить страницу несколько раз. Если не помогло – проверяем подключение к интернету.
Настройки Сети.
1. Некоторые сайты иногда «капризничают». Для динамического IP решение будет простым – перезагрузить роутер через отключение питания.
2. Медленное соединение иногда провоцирует ошибку ERR_CONNECTION_TIMED_OUT. Скорость работы интернета можно проверить через Яндекс-интернетометр. Если скорость слишком низкая – следует обратиться к интернет-провайдеру.
3. Необходимо проверить «Свойства сети» на наличие посторонних DNS-адресов. Если такие адреса имеются – удалить (предварительно на всякий случай переписав их куда-нибудь) и проверить систему на вирусы с помощью установленного на ПК антивирусного ПО – NOD32, Kaspersky, AdwCleaner, MalwareBytes, Dr.Web и т.д. Лучше всего для этих целей использовать Live-загрузчики.
4. Проверить настройки самого роутера. Наиболее часто сбивается параметр MTU. Универсальных рекомендаций по настройке роутера дать невозможно, т.к. это напрямую зависит и от модели роутера, и от интернет-провайдера. Обычно MTU имеет значения 1500, 1460, 1476.
Какое должно быть время ответа сервера?
И сразу же конкретные цифры:
— самая высокая конверсия у страниц, которые полностью загружаются за 1,8 и 2,7 секунды для десктопной и мобильной версий соответственно
— самый низкий показатель отказов у страниц, которые полностью загружаются за 1 и 0.7 секунды для десктопной и мобильной версий соответственно
Данные цифры позаимствованы из исследования Akamai Technologies.
Итак, Вы проверили сайт на скорость загрузки. Но как реагировать на результаты?
Как работать с ошибками бизнес-логики через HTTP
Почти все разработчики так или иначе постоянно работают с api по http, клиентские разработчики работают с api backend своего сайта или приложения, а бэкендеры «дергают» бэкенды других сервисов, как внутренних, так и внешних. И мне кажется, одна из самых главных вещей в хорошем API это формат передачи ошибок. Ведь если это сделано плохо/неудобно, то разработчик, использующий это API, скорее всего не обработает ошибки, а клиенты будут пользоваться молчаливо ломающимся продуктом.
За 7 лет я как поддерживал множество legacy API, так и разрабатывал c нуля. И я поработал, наверное, с большинством стратегий по возвращению ошибок, но каждая из них создавала дискомфорт в той или иной мере. В последнее время я нащупал оптимальный вариант, о котором и хочу рассказать, но с начала расскажу о двух наиболее популярных вариантах.
№1: HTTP статусы
Если почитать апологетов REST, то для кодов ошибок надо использовать HTTP статусы, а текст ошибки отдавать в теле или в специальном заголовке. Например:
Если у вас примитивная бизнес-логика или API из 5 url, то в принципе это нормальный подход. Однако как-только бизнес-логика станет сложнее, то начнется ряд проблем.
Http статусы предназначались для описания ошибок при передаче данных, а про логику вашего приложения никто не думал. Статусов явно не хватает для описания всего разнообразия ошибок в вашем проекте, да они и не были для этого предназначены. И тут начинается натягивание «совы на глобус»: все начинают спорить, какой статус ошибки дать в том или ином случае. Пример: Есть API для task manager. Какой статус надо вернуть в случае, если пользователь хочет взять задачу, а ее уже взял в работу другой пользователь? Ссылка на http статусы. И таких проблемных примеров можно придумать много.
REST скорее концепция, чем формат общения из чего следует неоднозначность использования статусов. Разработчики используют статусы как им заблагорассудится. Например, некоторые API при отсутствии сущности возвращают 404 и текст ошибки, а некоторые 200 и пустое тело.
Бэкенд разработчику в проекте непросто выбрать статус для ошибки, а клиентскому разработчику неочевидно какой статус предназначен для того или иного типа ошибок бизнес-логики. По-хорошему в проекте придется держать enum для того, чтобы описать какие ошибки относятся к тому или иному статусу.
Когда бизнес-логика приложения усложняется, начинают делать как-то так:
Из-за ограниченности http статусов разработчики начинают вводить “свои” коды ошибок для каждого статуса и передавать их в теле ответа. Другими словами, пользователю API приходится писать нечто подобное:
Из-за этого ветвление клиентского кода начинает стремительно расти: множество http статусов и множество кодов в самом сообщении. Для каждого ошибочного http статуса необходимо проверить наличие кодов ошибок в теле сообщения. От комбинаторного взрыва начинает конкретно пухнуть башка! А значит обработку ошибок скорее всего сведут к сообщению типа “Произошла ошибка” или к молчаливому некорректному поведению.
Многие системы мониторинга сервисов привязываются к http статусам, но это не помогает в мониторинге, если статусы используются для описания ошибок бизнес логики. Например, у нас резкий всплеск ошибок 429 на графике. Это началась DDOS атака, или кто-то из разработчиков выбрал неудачный статус?
Итог: Начать с таким подходом легко и просто и для простого API это вполне подойдет. Но если логика стала сложнее, то использование статусов для описания того, что не укладывается в заданные рамки протокола http приводит к неоднозначности использования и последующим костылям для работы с ошибками. Или что еще хуже к формализму, что ведет к неприятному пользовательскому опыту.
№2: На все 200
Есть другой подход, даже более старый, чем REST, а именно: на все ошибки связанные с бизнес-логикой возвращать 200, а уже в теле ответа есть информация об ошибке. Например:
На самом деле формат зависит от вас или от выбранной библиотеки для реализации коммуникации, например JSON-API.
Звучит здорово, мы теперь отвязались от http статусов и можем спокойно ввести свои коды ошибок. У нас больше нет проблемы “впихнуть невпихуемое”. Выбор нового типа ошибки не вызывает споров, а сводится просто к введению нового числового номера (например, последовательно) или строковой константы. Например:
Клиентские разработчики просто основываясь на кодах ошибок могут создать классы/типы ошибок и притом не бояться, что сервер вернет один и тот же код для разных типов ошибок (из-за бедности http статусов).
Обработка ошибок становится менее ветвящейся, множество http статусов превратились в два: 200 и все остальные (ошибки транспорта).
В некоторых случаях, если есть библиотека десериализации данных, она может взять часть работы на себя. Писать SDK вокруг такого подхода проще нежели вокруг той или иной имплементации REST, ведь реализация зависит от того, как это видел автор. Кроме того, теперь никто не вызовет случайное срабатывание alert в мониторинге из-за того, что выбрал неудачный код ошибки.
Но неудобства тоже есть:
Избыточность полей при передаче данных, т.е. нужно всегда передавать 2 поля: для данных и для ошибки. Это усложняет чтение логов и написание документации.
При использовании средств отладки (Chrome DevTools) или других подобных инструментов вы не сможете быстро найти ошибочные запросы бизнес логики, придется обязательно заглянуть в тело ответа (ведь всегда 200)
Мониторинг теперь точно будет срабатывать только на ошибки транспорта, а не бизнес-логики, но для мониторинга логики надо будет дописывать парсинг тела сообщения.
В некоторых случаях данный подход вырождается в RPC, то есть по сути вообще отказываются от использования url и шлют все на один url методом POST, а в теле сообщения передают все параметры. Мне кажется это не правильным, ведь url это прекрасный именованный namespace, зачем от этого отказываться, не понятно?! Кроме того, RPC создает проблемы:
нельзя кэшировать по http GET запросы, так как замешали чтение и запись в один метод POST
нельзя делать повторы для неудавшихся GET запросов (на backend) на реверс-прокси (например, nginx) по указанной выше причине
имеются проблемы с документированием – swagger и ApiDoc не подходят, а удобных аналогов я не нашел
Итог: Для сложной бизнес-логики с большим количеством типов ошибок такой подход лучше, чем расплывчатый REST, не зря в проектах c “разухабистой” бизнес-логикой часто именно такой подход и используют.
№3: Смешанный
Возьмем лучшее от двух миров. Мы выберем один http статус, например, 400 или 422 для всех ошибок бизнес-логики, а в теле ответа будем указывать код ошибки или строковую константу. Например:
400 – ошибка бизнес логики
остальное ошибки в транспорте
Тело ответа для удачного запроса у нас имеет произвольную структуру, а вот для ошибки есть четкая схема. Мы избавляемся от избыточности данных (поле ошибки/данных) благодаря использованию http статуса в сравнении со вторым вариантом. Клиентский код упрощается в плане обработки ошибки (в сравнении с первым вариантом). Также мы снижаем его вложенность за счет использования отдельного http статуса для ошибок бизнес логики (в сравнении со вторым вариантом).
Мы можем расширять объект ошибки для детализации проблемы, если хотим. С мониторингом все как во втором варианте, дописывать парсинг придется, но и риска “стрельбы” некорректными alert нету. Для документирования можем спокойно использовать Swagger и ApiDoc. При этом сохраняется удобство использования инструментов разработчика, таких как Chrome DevTools, Postman, Talend API.
Итог: Использую данный подход уже в нескольких проектах, где множество типов ошибок и все крайне довольны, как клиентские разработчики, так и бэкендеры. Внедрение новой ошибки не вызывает споров, проблем и противоречий. Данный подход объединяет преимущества первого и второго варианта, при этом код более читабельный и структурированный.
Самое главное какой бы формат ошибок вы бы не выбрали лучше обговорить его заранее и следовать ему. Если эту вещь пустить на “самотек”, то очень скоро обработка ошибок в проекте станет невыносимо сложной для всех.
P.S. Иногда ошибки любят передавать массивом
Но это актуально в основном в двух случаях:
Когда наш API выступает в роли сервиса без фронтенда (нет сайта/приложения). Например, сервис платежей.
Когда в API есть url для загрузки какого-нибудь длинного отчета в котором может быть ошибка в каждой строке/колонке. И тогда для пользователя удобнее, чтобы ошибки в приложении сразу показывались все, а не по одной.
В противном случае нет особого смысла закладываться сразу на массив ошибок, потому что базовая валидация данных должна происходить на клиенте, зато код упрощается как на сервере, так и на клиенте. А user-experience хакеров, лезущих напрямую в наше API, не должен нас волновать?HTTP
- списание денег на яндекс плюс что это
- примавера кафе октябрьское поле