API и протоколы
Знание API и протоколов, нужное аналитику для написания спецификаций — структура HTTP и коды состояния, принципы REST, сравнение стилей API, форматы данных и идемпотентность.
23 вопросов
JuniorТеорияОчень частоЧем различаются HTTP-методы GET, POST, PUT и PATCH?
Чем различаются HTTP-методы GET, POST, PUT и PATCH?
GET читает ресурс: безопасен, кэшируется, без тела. POST создаёт ресурс или запускает действие и не идемпотентен — повтор создаёт дубли. PUT полностью заменяет ресурс и идемпотентен. PATCH применяет частичное изменение к некоторым полям.
Типичные ошибки
- ✗Называть POST идемпотентным или PUT неидемпотентным
- ✗Путать PUT (полная замена) с PATCH (частичное изменение)
- ✗Забывать, что GET безопасен, кэшируется и без тела
Уточняющие вопросы
- →Почему PUT идемпотентен, а POST — нет?
- →Какой метод вы выберете для обновления одного поля ресурса?
JuniorТеорияОчень частоЧто такое RESTful-приложение и что значит «stateless» для сервера и клиента?
Что такое RESTful-приложение и что значит «stateless» для сервера и клиента?
RESTful-приложение моделирует данные как ресурсы, адресуемые URL и управляемые стандартными HTTP-методами. Stateless значит, что сервер не хранит сессию между вызовами — каждый запрос несёт свой контекст, поэтому клиент шлёт его заново, а обслужить может любой узел.
Типичные ошибки
- ✗Думать, что сервер хранит сессию под каждого клиента
- ✗Считать, что клиент может опускать контекст в новых запросах
- ✗Полагать, что ответить клиенту может только исходный узел
Уточняющие вопросы
- →Как отсутствие состояния помогает REST API масштабироваться?
- →Где хранятся сессионные данные, если не на сервере?
JuniorТеорияОчень частоКакие HTTP-методы безопасны, а какие идемпотентны — идемпотентен ли DELETE?
Какие HTTP-методы безопасны, а какие идемпотентны — идемпотентен ли DELETE?
Безопасные методы не меняют состояние сервера — GET, HEAD, OPTIONS. Идемпотентные оставляют то же состояние на повторе — GET, PUT, DELETE. DELETE идемпотентен — удаление дважды оставляет ресурс удалённым, хотя второй вызов вернёт 404. POST ни то, ни другое — повтор создаёт дубли.
Типичные ошибки
- ✗Считать безопасность и идемпотентность одним свойством
- ✗Называть DELETE неидемпотентным из-за последующего 404
- ✗Называть POST идемпотентным
Уточняющие вопросы
- →Почему повторный DELETE с 404 всё же идемпотентен?
- →Может ли безопасный метод быть неидемпотентным?
JuniorТеорияОчень частоВ чём разница между 200, 201, 202 и 204 — и между 401 и 403?
В чём разница между 200, 201, 202 и 204 — и между 401 и 403?
200 OK — успех с телом. 201 Created — создан ресурс, URL в Location. 202 Accepted — принят в асинхронную обработку, ещё не готов. 204 No Content — успех без тела. 401 значит «не аутентифицирован» (войдите); 403 — «аутентифицирован, но нет прав».
Типичные ошибки
- ✗Путать 201 Created с обычным 200 OK
- ✗Ставить 200 там, где нужен 202 (принято, асинхронно)
- ✗Менять местами 401 (не аутентифицирован) и 403 (нет прав)
Уточняющие вопросы
- →Какой код подходит долгому запросу, ещё не готовому?
- →Вошедший юзер бьёт в админ-роут — 401 или 403?
JuniorТеорияЧастоКуда помещают фильтрацию, сортировку и выбор полей на REST-эндпоинте?
Куда помещают фильтрацию, сортировку и выбор полей на REST-эндпоинте?
Все три идут в query-строке коллекции, не в пути. Фильтр по значениям полей — ?status=paid. Сортировка параметром — ?sort=-createdAt (минус — по убыванию). Выбор полей ради урезания ответа — ?fields=id,total. Они сочетаются на одном GET /orders и оставляют URL кэшируемым.
Типичные ошибки
- ✗Зашивать значения фильтра или сортировки в путь ресурса
- ✗Делать каждую комбинацию фильтров отдельным эндпоинтом
- ✗Думать, что GET не несёт query-параметров
Уточняющие вопросы
- →Как выразить сортировку по убыванию в query-строке?
- →Почему держать это в query, а не в пути?
JuniorТеорияЧастоКакова структура HTTP-запроса и ответа и какие классы кодов состояния вы знаете?
Какова структура HTTP-запроса и ответа и какие классы кодов состояния вы знаете?
HTTP-запрос состоит из строки запроса (метод + URL), заголовков и необязательного тела. Ответ — из строки статуса, заголовков и тела. Коды делятся на пять классов: 1xx информационные, 2xx успешные, 3xx перенаправления, 4xx клиентские, 5xx серверные.
Типичные ошибки
- ✗Забывать заголовки или тело как части сообщения
- ✗Менять местами смысл 4xx (клиент) и 5xx (сервер)
- ✗Не знать пять классов кодов состояния
Уточняющие вопросы
- →Что означает код 401 и чем он отличается от 403?
- →В каком классе код, означающий «ресурс перемещён»?
JuniorТеорияЧастоЧто такое OpenAPI/Swagger, что содержит спецификация и кто её потребляет?
Что такое OpenAPI/Swagger, что содержит спецификация и кто её потребляет?
OpenAPI (ранее Swagger) — машиночитаемое, независимое от языка описание REST API в YAML или JSON. Перечисляет пути, методы, параметры, схемы, коды состояния и auth. Инструменты потребляют его, чтобы рисовать документацию, генерировать заглушки, мокать API или гонять контрактные тесты.
Типичные ошибки
- ✗Думать, что OpenAPI запускает API, а не описывает его
- ✗Считать, что спецификацию читают только люди, а не инструменты
- ✗Забывать, что спецификация покрывает схемы, коды и auth
Уточняющие вопросы
- →Какие инструменты умеют генерировать из файла OpenAPI?
- →Как спецификация OpenAPI поддерживает контрактное тестирование?
JuniorТеорияЧастоКаких соглашений по именованию и структуре ресурсов REST вы придерживаетесь?
Каких соглашений по именованию и структуре ресурсов REST вы придерживаетесь?
Именуйте ресурсы существительными во множественном, не глаголами — /orders, /orders/42/items. Глагол — это HTTP-метод, поэтому избегайте /getOrder. Вкладывайте для принадлежности, но неглубоко; дальше связывайте по id. Пишите строчными с дефисами и держите шаблон предсказуемым.
Типичные ошибки
- ✗Кодировать действие глаголом в пути (
/getOrder) - ✗Вкладывать ресурсы слишком глубоко вместо связи по id
- ✗Использовать единственное число или разнобой в регистре
Уточняющие вопросы
- →Как выразить «позиции заказа 42» в виде пути?
- →Почему действие вообще не стоит держать в URL?
JuniorТеорияЧастоЧто несут заголовки запроса и какие заголовки ответа важны в REST — Content-Type, Location, ETag?
Что несут заголовки запроса и какие заголовки ответа важны в REST — Content-Type, Location, ETag?
Заголовки несут метаданные сообщения, отдельно от тела. Заголовки запроса включают Authorization (учётные данные) и Accept (желаемый формат). Ключевые заголовки ответа в REST — Content-Type (формат), Location (URL нового ресурса, с 201) и ETag (метка версии для кэша).
Типичные ошибки
- ✗Путать метаданные заголовков с телом сообщения
- ✗Не знать, что
Locationвозвращает URL созданного ресурса - ✗Забывать, что
ETagуправляет кэшем и условными запросами
Уточняющие вопросы
- →Какой заголовок возвращает URL нового ресурса?
- →Как
ETagпозволяет клиенту не скачивать ресурс заново?
JuniorТеорияЧастоЧто помещают в URL — path-параметры против query-параметров — и когда что применять?
Что помещают в URL — path-параметры против query-параметров — и когда что применять?
Path-параметры идентифицируют конкретный ресурс в пути — /orders/42 адресует один заказ. Query-параметры уточняют запрос к коллекции — фильтрацию, сортировку и пагинацию вида ?status=paid&page=2. Обязательные идентификаторы — в путь, необязательные модификаторы — в query.
Типичные ошибки
- ✗Класть обязательный id ресурса в query-строку
- ✗Слать фильтры или пагинацию как сегменты пути
- ✗Считать path- и query-параметры взаимозаменяемыми
Уточняющие вопросы
- →Куда вы поместите поисковый запрос по большому списку?
- →Должен ли необязательный фильтр быть сегментом пути?
MiddleДизайнЧастоСпроектируйте REST API корзины и оформления заказа книжного магазина. Пользователь смотрит книги, добавляет и убирает позиции корзины, затем оформляет заказ. Разложите ресурсы, HTTP-методы на каждом и коды состояния для основных успешных и ошибочных случаев.
Спроектируйте REST API корзины и оформления заказа книжного магазина. Пользователь смотрит книги, добавляет и убирает позиции корзины, затем оформляет заказ. Разложите ресурсы, HTTP-методы на каждом и коды состояния для основных успешных и ошибочных случаев.
Ресурсы — существительные: /books, /cart/items, /orders. GET /books — список (200), POST /cart/items — добавить (201), DELETE /cart/items/{id} — удалить (204), POST /orders — оформить (201 с Location). 404 — нет книги, 409 — пустая корзина, 422 — плохие данные. Оформление неидемпотентно.
Типичные ошибки
- ✗Кодировать действия глаголами в пути вроде
/addToCart - ✗Делать оформление GET-ом или идемпотентным PUT
- ✗Возвращать 200 или 500 там, где нужны 201/404/409
Уточняющие вопросы
- →Почему оформление — POST, а не PUT?
- →Какой код подходит добавлению книги не в наличии?
MiddleТеорияЧастоКак сделать POST идемпотентным — что такое ключ идемпотентности и где он хранится?
Как сделать POST идемпотентным — что такое ключ идемпотентности и где он хранится?
POST не идемпотентен, поэтому повтор может создать дубль. Клиент шлёт уникальный ключ идемпотентности в заголовке; сервер сохраняет его с первым ответом и на повторе возвращает сохранённый результат вместо повторного действия. Ключи живут в быстром хранилище с TTL.
Типичные ошибки
- ✗Ждать генерации ключа сервером, а не клиентом
- ✗Не хранить связь ключ–ответ для повторов
- ✗Игнорировать ключ и создавать новый ресурс на каждый вызов
Уточняющие вопросы
- →Почему ключ генерирует клиент, а не сервер?
- →Как долго стоит хранить сохранённый ключ идемпотентности?
MiddleДизайнЧастоКоманда доставки часто получает дублирующиеся заказы. Почему это происходит и как вы спроектируете защиту, чтобы один и тот же заказ не создавался дважды?
Команда доставки часто получает дублирующиеся заказы. Почему это происходит и как вы спроектируете защиту, чтобы один и тот же заказ не создавался дважды?
Дубли возникают, когда неидемпотентное создание (POST) повторяется после таймаута или двойного клика — запрос прошёл, но клиент не увидел ответа. Решение — ключ идемпотентности, который хранит бэкенд, чтобы повторный ключ вернул исходный результат.
Типичные ошибки
- ✗Винить базу вместо повторённого неидемпотентного создания
- ✗Пропускать уникальный ключ запроса/идемпотентности
- ✗Доверять клиенту и опускать серверную валидацию запросов
Уточняющие вопросы
- →Как бэкенд использует ключ идемпотентности при повторе?
- →Почему сетевой таймаут провоцирует повторную отправку заказа?
MiddleДизайнЧастоСпроектируйте пагинацию для большой растущей коллекции — например, ленты из миллионов событий. Объясните, как схема возвращает страницу и следующую, и что ломается в обычной offset/limit-пагинации на странице 10 000 или при вставке строк между запросами.
Спроектируйте пагинацию для большой растущей коллекции — например, ленты из миллионов событий. Объясните, как схема возвращает страницу и следующую, и что ломается в обычной offset/limit-пагинации на странице 10 000 или при вставке строк между запросами.
Предпочтите курсорную (keyset) пагинацию — клиент шлёт непрозрачный курсор на последнюю строку и получает следующий срез плюс nextCursor. Offset/limit деградирует на больших смещениях — БД сканирует и отбрасывает пропущенные строки, поэтому страница 10 000 медленна. Ещё она пропускает/повторяет строки при вставках.
Типичные ошибки
- ✗Брать offset/limit по умолчанию для глубокой массовой пагинации
- ✗Игнорировать пропуск/дубли строк при параллельных вставках
- ✗Думать, что большое смещение ничего не стоит базе
Уточняющие вопросы
- →Почему большое смещение остаётся медленным даже с индексом?
- →Как курсор избегает пропуска строк при вставках?
MiddleДизайнЧастоЭндпоинт оплаты должен отклонить заказ с истёкшим сроком карты. Заказ в остальном валиден, и клиент будет повторять. Спроектируйте ответ — какой HTTP-код вы вернёте, что содержит тело и должен ли клиент повторять автоматически или просить пользователя действовать.
Эндпоинт оплаты должен отклонить заказ с истёкшим сроком карты. Заказ в остальном валиден, и клиент будет повторять. Спроектируйте ответ — какой HTTP-код вы вернёте, что содержит тело и должен ли клиент повторять автоматически или просить пользователя действовать.
Верните клиентскую ошибку 4xx, не 5xx — на сервере ничего не сломалось. Подходит 422 — запрос корректен, но карта просрочена. Тело несёт машинный code (card_expired), сообщение и поле. Клиент не должен авто-повторять с той же картой; он должен попросить пользователя ввести новую.
Типичные ошибки
- ✗Ставить 5xx на клиентскую (карта) проблему
- ✗Возвращать 200 или пустое тело без кода ошибки
- ✗Авто-повторять ту же карту вместо запроса новой
Уточняющие вопросы
- →Почему здесь 422, а не 400?
- →Что позволяет клиенту обработать ошибку программно?
MiddleТеорияЧастоЧто такое REST и какие его основные принципы вы знаете?
Что такое REST и какие его основные принципы вы знаете?
REST — архитектурный стиль поверх HTTP, набор рекомендаций, а не протокол, как SOAP. Его ограничения: разделение клиент–сервер, отсутствие состояния, кэшируемость, единообразие интерфейса, многоуровневая система и необязательный code-on-demand.
Типичные ошибки
- ✗Называть REST протоколом, а не архитектурным стилем
- ✗Забывать про отсутствие состояния или единообразие интерфейса
- ✗Путать ограничения REST с обязательным конвертом SOAP
Уточняющие вопросы
- →Что значит «statelessness» на практике для сервера?
- →Почему REST называют рекомендательным, а не обязательным?
MiddleТеорияЧастоСравните стили API — SOAP, REST, gRPC и GraphQL — и где какой уместен.
Сравните стили API — SOAP, REST, gRPC и GraphQL — и где какой уместен.
SOAP — строгий протокол на XML с контрактами XSD/WSDL — формален, но тяжёл. REST — стиль поверх HTTP со стандартными методами — прост и повсеместен. gRPC — protobuf поверх HTTP/2 со стримами — быстр для бэкенд-к-бэкенду. GraphQL — один endpoint.
Типичные ошибки
- ✗Называть SOAP стилем, а REST протоколом (наоборот)
- ✗Приписывать protobuf/стримы HTTP/2 REST'у, а не gRPC
- ✗Забывать про единый endpoint GraphQL и выборку полей
Уточняющие вопросы
- →Когда вы предпочтёте gRPC, а не REST?
- →Какую проблему over-fetching решает GraphQL?
MiddleТеорияЧастоМожно ли использовать POST для чтения и GET для создания? Что сломается, если так делать?
Можно ли использовать POST для чтения и GET для создания? Что сломается, если так делать?
Сервер выполнит любой обработчик, но вы ломаете контракт методов. GET безопасен и кэшируется — прокси и краулеры могут предзагружать/повторять его, поэтому создающий данные GET сам вызовет побочные эффекты и может быть неверно закэширован. POST не кэшируется, чтение им теряет кэш. Методы значат заявленное.
Типичные ошибки
- ✗Считать, что метод не влияет на кэши и краулеры
- ✗Забывать, что создающий GET сработает при предзагрузке/повторе
- ✗Читать через POST и терять кэшируемость
Уточняющие вопросы
- →Чем опасен создающий GET при предзагрузке браузера?
- →Какая выгода кэша теряется при чтении через POST?
MiddleТеорияЧастоКак версионируют API и какие изменения обратно совместимы, а какие ломающие?
Как версионируют API и какие изменения обратно совместимы, а какие ломающие?
Стратегии — версия в URI (/v2/orders), кастомный заголовок или media-type в Accept; URI проще, заголовки чище. Добавить необязательное поле или эндпоинт — обратно совместимо. Удалить/переименовать поле, сменить тип, ужесточить валидацию — ломающее, нужна новая версия.
Типичные ошибки
- ✗Считать новое обязательное поле обратно совместимым
- ✗Считать любое, даже аддитивное, изменение ломающим
- ✗Думать, что клиенты сами примут удалённые/переименованные поля
Уточняющие вопросы
- →Ломающее ли добавление нового обязательного поля запроса? Почему?
- →Когда выберете заголовок вместо версии в URI?
SeniorДизайнЧастоЭндпоинт должен вернуть отчёт, который строится около трёх минут, а синхронный запрос отвалится по таймауту на шлюзе. Спроектируйте REST-взаимодействие так, чтобы клиент запустил задачу, узнал о её завершении и забрал результат — опишите ресурсы, коды состояния и как клиент проверяет прогресс, не держа соединение открытым.
Эндпоинт должен вернуть отчёт, который строится около трёх минут, а синхронный запрос отвалится по таймауту на шлюзе. Спроектируйте REST-взаимодействие так, чтобы клиент запустил задачу, узнал о её завершении и забрал результат — опишите ресурсы, коды состояния и как клиент проверяет прогресс, не держа соединение открытым.
Сделайте асинхронно. POST /reports запускает задачу и возвращает 202 с Location на /reports/{id}. Клиент опрашивает GET /reports/{id}, получая 200 со статусом (pending/running/done), пока идёт сборка. По готовности — результат или 303 на ресурс результата. Это переживает таймаут шлюза.
Типичные ошибки
- ✗Держать вызов синхронным и бороться с таймаутом шлюза
- ✗Слать POST заново вместо опроса ресурса задачи
- ✗Возвращать 200/500 вместо 202 и ресурса статуса
Уточняющие вопросы
- →Почему 202 и
Location, а не 200 с отчётом? - →Как клиент узнает, сколько ждать между опросами?
SeniorДизайнЧастоМобильное приложение показывает «неизвестная ошибка» на любой сбой, потому что API возвращает голые 500 с HTML-страницей или пустым телом. Перепроектируйте контракт ошибок, чтобы клиент различал случаи и действовал — отделите ошибку валидации, отсутствующий ресурс, проблему авторизации и временный серверный сбой и скажите, что делать в каждом.
Мобильное приложение показывает «неизвестная ошибка» на любой сбой, потому что API возвращает голые 500 с HTML-страницей или пустым телом. Перепроектируйте контракт ошибок, чтобы клиент различал случаи и действовал — отделите ошибку валидации, отсутствующий ресурс, проблему авторизации и временный серверный сбой и скажите, что делать в каждом.
Верните правильный класс статуса и единообразное JSON-тело — стабильный машинный code, message, детали по полям. Валидация → 422; нет ресурса → 404; авторизация → 401/403; временный сбой → 503 с Retry-After (повтор с backoff). code управляет логикой клиента; класс говорит, чья ошибка.
Типичные ошибки
- ✗Ставить один статус (500 или 400) на все виды сбоя
- ✗Возвращать HTML или пустое тело вместо структурного JSON
- ✗Опускать стабильный код, по которому ветвится клиент
Уточняющие вопросы
- →Какой заголовок говорит клиенту, когда повторить 503?
- →Почему ветвиться по
code, а не по тексту сообщения?
JuniorТеорияИногдаКакие форматы данных нужны аналитику для спецификаций — JSON, YAML, XML, XSD, WSDL?
Какие форматы данных нужны аналитику для спецификаций — JSON, YAML, XML, XSD, WSDL?
JSON — текстовый формат обмена (json-schema описывает его структуру). YAML — человекочитаемый формат в конфигах и спецификациях. XML — многословная разметка; XSD задаёт структуру XML-документа, а WSDL описывает операции SOAP-сервиса.
Типичные ошибки
- ✗Путать, что описывает XSD (XML), с json-schema (JSON)
- ✗Считать WSDL форматом данных, а не описанием сервиса
- ✗Думать, что формат валидирует себя без схемы
Уточняющие вопросы
- →Чем XSD отличается от WSDL?
- →Когда вы выберете JSON, а когда XML для интеграции?
MiddleТеорияИногдаКаковы уровни зрелости Ричардсона и что добавляет HATEOAS?
Каковы уровни зрелости Ричардсона и что добавляет HATEOAS?
Модель Ричардсона оценивает зрелость REST по четырём уровням. Уровень 0 — один URI, один метод. Уровень 1 — много ресурсов, каждый с URI. Уровень 2 — правильные методы и коды, где сидит большинство API. Уровень 3 добавляет HATEOAS — ответы встраивают ссылки на действия, и клиент ходит по ним.
Типичные ошибки
- ✗Не знать, что большинство API живёт на уровне 2
- ✗Путать HATEOAS с кэшированием или аутентификацией
- ✗Упускать, что HATEOAS — навигация по ссылкам
Уточняющие вопросы
- →Какого уровня достигает большинство боевых REST API?
- →Какую практическую пользу дают клиенту встроенные ссылки?