
Мы поговорим про основные ошибки, которые очень часто допускаются при проектировании “с нуля” в REST API на примере базового взаимодействия между клиентом и сервером в системе.
Самая частая проблема, с которой у многих всё начинается — это “проблема чистого листа”. Возникает она по разным причинам:
отсутствие опыта и/или знаний;
привычка готовить описание по готовому шаблону, который в данный момент отсутствует;
недостаток требований и тд.
Поэтому мы и поговорим о том, как описать API метод “с чистого листа” и избежать при этом наиболее распространенных ошибок.
Итак, “3 кита” неудачного описания API-метода:
№1: Не системная постановка задачи: объемное описание бизнес-процесса и отсутствие технического контекста
Не смотря на то, что это, казалось бы, однозначно проблема, тем не менее среди разработчиков выделяется два фронта:
Те, для кого — это реально проблема. Аналитика забрасывают дополнительными вопросами, разработчики ничего не хотят додумывать сами, им нужна четкая системная постановка от аналитика.
Те, кого устраивает бизнес постановка, как правило — это команды с сильным тех. лидом разработки. Они осознанно, самостоятельно преобразуют бизнес-постановку в системную, так как считают, что backend знают лучше аналитика.
В целом, и тот, и другой варианты имеют место быть. Второй вариант, однако, считаю менее удачным, но это скорее философский вопрос.
№2: Постановка системная, НО не структурирована, описание хаотично
Данная проблема обычно возникает, когда в команде работает несколько аналитиков, но нет согласованности в описании структуры постановки задачи или, возможно, это молодой проект/команда, в которых еще не выработаны системные подходы.
Это может происходить по разным причинам: нет времени на проработку шаблонов, нет желания советоваться с разработчиками, поджимают сроки проекта, работает принцип “и так сойдет” и т.д.
Если проект небольшой, то возможно эта проблема затеряется и будет почти не ощутима, но если проект большой, активно развивающийся, постоянно приходят новые разработчики/аналитики, то отсутствие упорядоченной структурированной аналитики, особенно по API, окажется огромной проблемой.
Разрабатываемая система рискует стать нестабильной в поведении и абсолютно неподдерживаемой.
Справедливости ради стоит сказать, что в последние годы эта проблема становится менее актуальной. Команды стараются внедрять шаблоны, следить за наличием упорядоченного, структурированного описания.
№3: Системная, структурированная постановка, но с ошибками и неполным описанием
Данная проблема чаще всего возникает от невнимательности или отсутствия опыта. В результате получается неполное описание, которое читает разработчик, не понимает, что нужно сделать и возвращается обратно к нам. Приходится дописывать и/или переписывать, на что тратится время и нервы: и наши, и разработки, и заказчика.
Вот так может выглядеть усредненная, базовая структура описания проектируемого API метода REST:
Назначение метода, целевой результат метода (Метод предназначен для….. В результате запроса будет ….)
Доступы и ограничения (Только авторизованные пользователи с ролью….Лимит: до 50 запросов/мин на аккаунт)
-
Требования к запросу:
Тип HTTP метода (POST, GET, PUT, DELETE, PATCH…)
Базовый URL (https://madela.dev)
Указатель на каталог api, сервис, версия, endpoint (/api/seller-doc/v1/orders)
Авторизация (роли, обязательность, способ)
Заголовки (указываются, если настраиваются для каждого запроса отдельно)
Пример запроса (POST https://madela.dev/api/seller-doc/v1/orders)
Параметры запроса (при наличии)
Тело запроса (при наличии)
Общее описание алгоритма
-
Требования к ответу:
Успешный ответ: описание, код HTTP, тело ответа
Обработка ошибок: описание, статус, тело ответа
Дополнительно можно указать: требование к логированию, мониторингу, мэппингу данных
Далее разберем типичные ошибки в каждом из перечисленных блоков структуры описания и как их избежать.
Типичные ошибки при описании REST API
1: Неправильно выбранный тип метода
Хочу напомнить про основные запросы:
GET — получить,
POST — создать,
PUT — изменить (полная перезапись) или создать,
PATCH — изменить,
DELETE — удалить.
Однако бывают нестандартные запросы, в которых такая стандартная схема отходит от базовых значений. Например, получить данные можно не только через GET, но и через POST, когда у нас очень большое количество параметров.
Часто также путают PATCH и PUT. Согласно определению PUT — это полное обновление ресурса, его перезапись, тогда как PATCH — это частичное обновление ресурса. Здесь важно помнить, что PUT если не найдет указанный для перезаписи ресурс, то создаст его. Также стоит помнить, что в случае с PUT мы указываем полный перечень параметров ресурса, тогда как для PATCH только обновляемые.
2: Игнорирование версионности API
Не всегда корректно указывать endpoint, начиная со слэша и названия ресурса. Если это небольшой новый проект или стартап, то разработчики, возможно, и сами разберутся, но на больших проектах игнорирование версии понесёт за собой только задержки в разработке и путаницу.
3: Некорректное указание ресурса
Из опыта могу сказать, что при указании ресурса не надо бояться избыточности и максимально полно приводить описание: включая полностью каталог и микросервис (в случае с микросервисной архитектурой), версию, endpoint и, при необходимости, дополнительные параметры. Если разработчик какие-то моменты и сам понимает, то с нашим описанием лишний раз перепроверит себя — это лучше, чем возврат постановки на уточнение и доработку.
Многие путают понятия URL и URI, а некоторые и вовсе не знают, что такое URI. URI (Uniform Resource Identifier) — это некий индивидуальный идентификатор ресурса, с которым мы хотим что-либо сделать. Очень часто в командах его называют обобщенно — endpoint. Термин URI используется не всегда, но знать его всё-таки нужно.
Банальный, но очень важный совет аналитикам: когда мы начинаем проектировать API-методы и именовать ресурсы, мы обязательно смотрим на модели данных, которые у нас есть. Сначала советуют проектировать модель данных. Если дорабатываем систему, то сначала обязательно проектировать кусочек данных, таблицы, атрибуты, поля, с которыми будут работать API-методы, а потом от них уже проектировать API с указанием endpoint, которые будут соотноситься с данными нашей модели данных.
Важным является также соблюдение иерархии данных. Она точно так же, как именование ресурсов, должна соотноситься с моделью данных и быть выстроена, спроектирована до того, как мы приступили к непосредственному проектированию API-метода.
И самая часто встречающаяся дилемма — как же именовать ресурсы? В единственном или множественном числе? Главное правило: придерживаться смысла и логики. Если это список, то лучше писать во множественном; если мы получаем данные об одном объекте по ID, то будет логичнее использовать единственное число.
В итоге:
Именование соответствует достигнутым договоренностям и концептуальной модели данных;
Продумана логическая организация их иерархии (подресурсы и глаголы в конце).
Объект имеет уникальный идентификатор URI: чаще существительное, чаще во мн. ч.;
4: Избыточные глаголы в URL
Часто встречается ситуация, когда после endpoint нужно добавить глагол. Здесь важно понимать, что глагол использовать можно, но он не должен повторять суть глагола метода, который мы используем для API-метода.
Например, в POST.../api/order/v1/create использование глагола create может только создать путаницу.
5: Некорректная последовательность в примере URL
Тоже часто встречающаяся ошибка. При записи URL необходимо следовать схеме:
ПРОТОКОЛ :// ДОМЕННОЕ ИМЯ / указатель на каталог API / ИМЯ API или микросервиса / ВЕРСИЯ API / РЕСУРС / РЕСУРС ID (при наличии) / ДЕЙСТВИЕ (при наличии) / QUERY-ПАРАМЕТРЫ (при наличии)
6: Некорректно описанные параметры
Согласно правилам, параметры делятся на три категории:
query-parameters или параметры запроса: обычно перечисляют после символа
?и разделяют&, если их много; необязательны; чаще всего используются для GET и DELETE, т.к. у них нет поддержки body-параметров (json). Применение: фильтры, сортировки, пагинация, api-key и другие параметры авторизации.path-parameters или параметры пути запроса: параметры, которые входят в состав endpoint ДО символа
?; обязательны, если используются; применяются для всех методов HTTP. Применение: показать, каким конкретно объектом по ID будет управлять метод.body-parameters или параметры тела запроса: используются в теле запроса; формат json, xml, html, text, javascript, или файлы; используются только для методов POST, PUT, PATCH. Применение: передача подробной информации об объекте данных, который надо создать или изменить.
Что важно при описании параметров:
Наименование;
Описание, назначение (кратко, емко);
Обязательность заполнения/наличия значения (null/not null);
Тип данных;
Пример значения.
Советую описание списка параметров приводить в табличном виде.
7: Недостаточное или некорректное описание алгоритма
Слишком бизнесовое описание, отсутствие технической (системной) составляющей;
Игнорирование ключа идемпотентности и дополнительных проверок на наличие данных в БД;
Недостаток схем алгоритма, диаграмм взаимодействия;
Избыток схем алгоритма, диаграмм взаимодействия;
Неатомарные операции в пределах одного сервиса.
8: Некорректное описание кодов и формата ответа
Очень часто путают коды ответов 200 и 201.
200 — запрос принят и корректно обработан, в ответе как правило не возвращается ничего кроме “ок”.
201 — запрос корректно обработан и в результате был создан новый ресурс, данные которого обычно присылаются в ответе.
Был интересный кейс от разработки, когда они спросили: “Если нет данных, что нам возвращать: пустой массив или 404?”. Между ними есть разница: 404 — это отсутствие ресурса как такового, а пустой массив — это просто отсутствие данных на ресурсе, то есть ресурс есть, но данных нет. На фронте это можно обернуть в различные информационные сообщения для того, чтобы пользователь понимал, что происходит и почему сервер отдаёт такой ответ.
К другим более мелким проблемам относятся:
Потеря требований к сортировке
В постановке не учли требования к пагинации
Недостаточное описание обработки ошибок
Для каждой ошибки рекомендуется формировать структурированное JSON-тело с уникальным кодом, понятным описанием и ссылкой на документацию — использовать стандартизированный JSON-ответ об ошибке.
Заключение
В качестве заключения стоит сказать, что результат проектирования API — это не только постановка для команды разработки, но и часть проектной базы аналитики. То насколько грамотно, структурировано и четко это будет описано является залогом качественной разработки и доработки системы, её технической поддержки, развития и масштабируемости.