Почти любое API, которое тестировщик проверяет руками или автотестами, говорит по HTTP. Если понимать, из чего состоит запрос и что означает каждая его часть, половина вопросов на собесе отвечается сама.
Запрос и ответ
HTTP это текстовый (в HTTP/1.1) протокол «вопрос-ответ». Клиент отправляет запрос, сервер возвращает ответ.
POST /api/orders?source=app HTTP/1.1
Host: shop.ru
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...
{"productId": 7, "qty": 1}
- Стартовая строка: метод (
POST), путь с query-строкой (/api/orders?source=app), версия. - Заголовки: метаданные. Кто мы, что шлём, что хотим получить.
- Пустая строка, затем тело (есть не всегда).
Ответ устроен так же, только в первой строке код и фраза:
HTTP/1.1 201 Created
Location: /api/orders/501
Content-Type: application/json
{"id": 501, "status": "new"}
Из чего состоит URL
https://shop.ru:443/api/v1/orders/77/items?status=paid&page=2#top
httpsсхема,shop.ruхост,443порт (для https по умолчанию)./api/v1/orders/77/itemsпуть.77это path-параметр, идентификатор в пути.status=paid&page=2query-параметры после?, разделены&.#topфрагмент, на сервер не отправляется.
Спецсимволы в значениях кодируются (percent-encoding): пробел %20, & это %26. Если в поиск подставить кофе & чай без кодирования, сервер увидит два параметра. Это классический баг.
Методы
| Метод | Зачем | Безопасный | Идемпотентный |
|---|---|---|---|
| GET | прочитать | да | да |
| HEAD | как GET, но без тела | да | да |
| OPTIONS | что разрешено (в том числе CORS preflight) | да | да |
| POST | создать или запустить обработку | нет | нет |
| PUT | заменить ресурс целиком | нет | да |
| PATCH | изменить часть ресурса | нет | не обязательно |
| DELETE | удалить | нет | да |
Безопасный значит «не меняет состояние сервера». Идемпотентный значит «повтор запроса даёт то же состояние, что один вызов». Обратите внимание: идемпотентность про состояние, а не про ответ. Первый DELETE /items/5 вернёт 204, второй 404, но товар удалён в обоих случаях.
Что из этого следует для тестов:
GETне должен ничего менять. Если ссылка «удалить» сделана через GET, её «нажмёт» любой краулер.- Повторный
POSTсоздаёт второй объект. Сеть сама порождает повторы: таймаут, ретрай мобильного клиента, двойной клик. Для заказов и оплат нужна защита, например заголовокIdempotency-Key. PUTс частью полей по смыслу должен заменить ресурс целиком. Проверьте, что API не обнуляет молча остальные поля, если это не задокументировано.
Stateless
HTTP не помнит прошлых запросов. Каждый запрос несёт всё нужное: cookie сессии или токен в Authorization. Поэтому в Postman запрос без токена получит 401, даже если минуту назад вы «логинились» другим запросом.
Версии
Смысл (методы, коды, заголовки) одинаков во всех версиях, меняется транспорт:
- HTTP/1.1: текст, одно соединение обслуживает запросы по очереди.
- HTTP/2: бинарный, много запросов параллельно в одном TCP-соединении, сжатие заголовков. Браузеры используют его только с HTTPS.
- HTTP/3: поверх QUIC (UDP), потеря пакета не тормозит соседние запросы.
В DevTools версия видна в колонке Protocol (h2, h3).
Путь запроса
Когда клиент впервые идёт на https://api.shop.ru: DNS превращает имя в IP, поднимается TCP-соединение, поверх него TLS с проверкой сертификата, и только потом уходит HTTP-запрос. Это карта для разбора ошибок: Could not resolve host про DNS, Connection refused про порт и сервис, ошибка сертификата про TLS, а код 4xx или 5xx значит, что до HTTP вы уже добрались.
Частые ошибки
- Путать безопасность и идемпотентность.
PUTидемпотентен, но не безопасен. - Передавать пароли и токены в query-строке: адрес оседает в логах и истории.
- Считать, что лишний
OPTIONSперед запросом в DevTools это дубль. Это CORS preflight. - Отправлять тело в GET и удивляться, что прокси его выкинул.
Что спросят на собесе
- Чем GET отличается от POST?
- Какие методы идемпотентны и почему DELETE идемпотентен, хотя второй вызов даёт 404?
- Чем PUT отличается от PATCH?
- Из чего состоит HTTP-запрос и URL, где path-, а где query-параметры?
- Что происходит, когда вы вводите адрес в браузере?