Какие принципы построения REST API существуют?
Что проверяют
Отличаете ли вы архитектурные ограничения REST от набора привычек вроде «ресурсы во множественном числе». Хороший ответ связывает принципы с кодом на FastAPI или Django REST Framework. Следом спрашивают про идемпотентность и разницу между PUT и PATCH.
Как отвечать
Сначала ограничения, как их сформулировал Рой Филдинг:
- клиент-сервер: интерфейс и хранение данных развиваются независимо;
- отсутствие состояния: каждый запрос несёт всё нужное, включая токен. Сервер не хранит сессию между запросами, поэтому инстансы легко масштабировать;
- кешируемость: ответ сам говорит, можно ли его кешировать, через
Cache-ControlиETag; - единый интерфейс: ресурсы адресуются URI, операции выражены методами HTTP, сообщения самоописательны, а в строгом варианте есть HATEOAS, ссылки на доступные действия прямо в ответе;
- многоуровневость: между клиентом и сервером стоят прокси, балансировщики, кеши, и клиент этого не замечает.
Дальше практика. GET, PUT, DELETE идемпотентны, POST нет, PATCH идемпотентным не гарантирован. Коды по смыслу: 201 Created с заголовком Location, 204 для пустого ответа, 400 или 422 на невалидные данные, 401 без аутентификации и 403 без прав, 409 при конфликте. В FastAPI код задают через status_code=201 в декораторе, а ошибку валидации Pydantic фреймворк сам отдаёт как 422. В DRF ModelViewSet с роутером раскладывает list, create, retrieve, update, partial_update, destroy по методам и URL. Добавьте версионирование (/api/v1/), пагинацию и фильтры в query-параметрах.
Где спотыкаются
Говорят, что все операции REST должны быть идемпотентными. POST создаёт новый ресурс на каждый вызов, поэтому для платежей и заказов вводят ключ идемпотентности в заголовке.
Путают идемпотентность с одинаковым ответом. Повторный DELETE может вернуть 404, но состояние сервера не меняется, и метод остаётся идемпотентным.
Называют REST любой JSON поверх HTTP, где всё идёт через POST /api/doAction. Это RPC, и на вопросе про модель зрелости Ричардсона такой ответ проваливается.