
Краткий гайд по наведению порядка HTTP status code и тому, как действовать если реальность становится по-настоящему пугающей.
Представим совершенно невероятную ситуацию: компания-стартап почувствовала потребность в системном аналитике и наняла своего первого специалиста. Знакомство с командой прошло позитивно, аналитик получил все необходимые доступы сразу. Он изучает продукт компании и получает первую задачу: спроектировать новый API endpoint с применением архитектурного стиля REST.
Он запускает несколько методов… и дальше начинает происходить что-то сверхъестественное:
200 OK оказался не тем, чем кажется, и содержит в теле описание ошибки;
500 Internal Server Error отображается вместо ошибки клиента;
документации нет, как и обоснования выбора того или иного кода ответа.
В дверь аналитика кто-то постучал.
В этой статье мы разберём примеры отхождения от REST-практик и попытаемся сформировать подход, который поможет шаг за шагом навести порядок в API. Берём с собой блокнот, ручку, фонарик и начинаем писать бестселлер выявлять расхождение с REST-практиками.
Шаг 1. Документация
Первый документ, который необходимо держать под рукой – это Раздел 15 Спецификации RFC 9110 – HTTP Semantics (2022).
Документ поведает базу – категорий состояний кодов ответа сервера всего пять:
1xx | Запрос получен, идёт обработка. |
2xx | Запрос выполнен успешно. |
3xx | Чтобы завершить запрос следуйте подсказке (например, перейти по ссылке). |
4xx | Ошибка на стороне клиента. |
5xx | Ошибка на стороне сервера. |
Какие из них рекомендованы в RESTful API, можно посмотреть тут и тут (не официальная документация, а шпаргалка). Мы пропустим Info и Redirection и, обойдёмся необходимым минимумом.
Шаг 2. Проводим исследование
Теперь пришло время определить масштабы бедствия. Проходимся по основным методам и сверяем запросы/ответы, выявляем закономерности. Будем использовать браузер (F12 + Network и далее Headers – запросы, а Response для ответов).
Представим, что у нас приложение по управлению онлайн магазином со следующими функциональностями:
Просмотр Карточки товара.
Создание Карточки товара.
Редактирование Карточки товара.
Примеры типовых несоответствий практикам REST:
Просмотр Карточки товара.
Метод используется для просмотра данных, нет чувствительных данных в запросе, сам запрос не превышает 2000 символов, но используется POST … getSubject, в ответ приходит 200 OK.
Создание Карточки товара.
В ответ на метод создания ресурса POST … subjectsList приходит 200 OK.
Ответы на 400 Bad Request не содержат информации о поле, в котором была допущена ошибка.
Допустим, мы можем создавать дубли товаров (т.е. c одинаковым полем “name”). В ответ мы получили 500 Internal server error. Описания поля с ошибкой в этом случае не предусмотрено.
Редактирование Карточки товара.
В ответ на PUT … Subjects/{id} приходит 409 Conflict без указания поля в котором находится ошибка.
Допустимо изменение id.
Фиксируем наши находки, маркируем их как результат AS IS и двигаемся дальше. Примеры ниже.
1. Метод: Просмотр карточки товара
Проблематика | 1. Использование небезопасного метода без предпосылок. |
Метод | POST … getSubject |
Описание | Метод для получения карточки по id |
Тело запроса |
|
200 | OK |
2. Метод: Создание карточки товара
Проблематика | 1. Ответ не содержит информации о создании ресурса. |
Метод | POST … subjectsList |
Описание | Метод для создания карточки товара |
Тело запроса |
|
200 | OK |
500 | Internal Server Error |
3. Метод: Редактирование карточки товара
Проблематика | 1. Ответ не содержит описания поля, в котором находится ошибка. |
Метод | PUT … Subjects/{id} |
Название | Редактирование карточки товара |
Описание | Метод для создания карточки товара |
Тело запроса |
|
200 | OK |
Шаг 3. Успешные статус-коды
Попробуем переработать существующую концепцию.
Просмотр Карточки товара. Намечаем, что неплохо перевести POST … getSubject в GET … v1/Subjects/{id}, и оставить 200 OK в соответствии с гайдом.
Создание Карточки товара. Ответ POST … v1/Subjects корректируем на 201 Created, потому что запрос был успешно обработан, и в результате был создан новый ресурс (201 Created по гайду).
Редактирование Карточки товара. Ничего не меняем, оставляем 200 OK поскольку создания нового ресурса не происходит. Однако, уберём возможность редактировать id.
Шаг 4. Ошибки Клиента
Определимся с тем, что может пойти не так на стороне Клиента.
Создание карточки товара:
400 Bad Request подходит для замены 500 Internal server error. Например, мы не указали количество товара. Обязательно указываем поле, непрошедшее валидацию в теле ответа.
409 Conflict в ситуации, когда например мы Создаем/Редактируем карточку товара и вводим наименование уже существующего товара, а дубли в нашей системе запрещены. Как и ранее, в тексте ошибки указываем на поле с некорректными данными.
Редактирование карточки товара. Забираем уже обозначенные выше ошибки:
400 Bad Request валидация одного из полей завершилась ошибкой.
409 Conflict для дублей, как и в карточке создания.
Шаг 5. Ошибки Сервера
Определим, что ошибка сервера теперь не имеет отношения к валидации полей:
Создание Карточки товара.
500 Internal Server Error – базовая ошибка сервера. Например, в ходе выполнения любого из запросов произошла непредвиденная ошибка сервера.
Шаг 6. Подготовка описания API
Теперь нам необходимо подготовить фактуру для будущего обсуждения. У нас должен получиться черновик с видением TO BE (см. Пример ниже). В ходе обсуждения можно будет также узнать почему в компании существовал подход, используемый ранее, почему REST считается ему хорошей альтернативой, а ещё – глубже понять техническую реализацию проекта.
1. Метод: Просмотр карточки товара
Метод | GET … v1/Subjects/{id} |
Название | Просмотреть карточку товара |
Описание | Метод для получения карточки по id |
200 | OK |
500 | Internal Server error |
2. Метод: Создание карточки товара
Метод | POST … v1/Subjects |
Название | Создать карточку товара |
Описание | Метод для создания карточки товара |
201 | Created |
400 | Bad Request |
Тело ответа |
|
409 | Conflict |
Тело ответа |
|
500 | Internal Server Error |
Тело ответа |
|
3. Метод: Редактирование карточки товара
Метод | PUT … v1/Subjects |
Название | Редактировать карточку товара |
Тело ответа | Метод для редактирования карточки товара |
409 | Conflict |
Тело ответа |
|
Заключение
Мы понимаем, что общеизвестные практики могут заменяться на частные, а подходы в разных компаниях могут отличаться. Однако, мы надеемся, что описанный нами подход, поможет менее опытным аналитикам найти отправную точку и почувствовать почву под ногами.
И самое важное – не забывать, что, работая над документацией, мы не следуем по кругу – мы переходим на новый виток ;)