HTTP и REST API: клиент-серверное взаимодействие

Структура HTTP-запроса и ответа, методы GET и POST, коды состояния, принципы REST, проектирование эндпоинтов, аутентификация по токену и документирование API.

Практически любая современная курсовая по разработке содержит клиент и сервер, общающиеся по HTTP. Разберём, как устроен этот обмен и как спроектировать API, за которое не будет стыдно на защите.

Структура запроса и ответа

POST /api/orders HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...
Content-Length: 58

{"productId": 42, "quantity": 3, "comment": "срочно"}

--- ответ ---

HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/orders/1024

{"id": 1024, "status": "new", "createdAt": "2026-08-17T10:15:00Z"}

Методы

МетодНазначениеИдемпотентенТело запроса
GETПолучить данныеДаНет
POSTСоздать ресурсНетДа
PUTЗаменить целикомДаДа
PATCHИзменить часть полейНетДа
DELETEУдалитьДаОбычно нет
Идемпотентность означает: повторный одинаковый запрос не меняет результат. Поэтому GET можно кэшировать и повторять при обрыве связи, а POST — нет: два вызова создадут два заказа. Именно из-за этого браузер предупреждает о повторной отправке формы.

Коды состояния

КодЗначениеКогда
200 OKУспехGET, успешный PATCH
201 CreatedРесурс созданPOST, в заголовке Location — адрес нового ресурса
204 No ContentУспех без телаDELETE
301 / 302ПеренаправлениеСмена адреса, постоянная и временная
400 Bad RequestОшибка в данных запросаНе прошла валидация
401 UnauthorizedНе аутентифицированНет или истёк токен
403 ForbiddenНет правАутентифицирован, но доступ запрещён
404 Not FoundРесурс не найденНеверный id или путь
409 ConflictКонфликт состоянияДубликат, нарушение уникальности
422Данные корректны по формату, но не по смыслуЧасто вместо 400
429Слишком много запросовСрабатывание ограничителя
500 Internal Server ErrorОшибка на сервереНеобработанное исключение

Разница между 401 и 403 — популярный вопрос: первый означает «мы не знаем, кто вы», второй — «знаем, но вам нельзя». Возврат 200 с текстом ошибки в теле считается плохой практикой: клиент не может отличить успех от сбоя, не разбирая содержимое.

Принципы REST

Хорошо                              Плохо
GET    /api/products                GET  /api/getAllProducts
GET    /api/products/42             GET  /api/product?id=42
POST   /api/products                POST /api/createProduct
PATCH  /api/products/42             POST /api/updateProduct
DELETE /api/products/42             GET  /api/deleteProduct?id=42
GET    /api/products?category=r&page=2   GET /api/productsByCategoryPage2

Сервер на Express

const express = require('express');
const app = express();
app.use(express.json());

const orders = [];

app.get('/api/orders', (req, res) => {
  const { status, page = 1, limit = 20 } = req.query;
  let result = status ? orders.filter(o => o.status === status) : orders;
  const start = (page - 1) * limit;
  res.json({ total: result.length, items: result.slice(start, start + Number(limit)) });
});

app.get('/api/orders/:id', (req, res) => {
  const order = orders.find(o => o.id === Number(req.params.id));
  if (!order) return res.status(404).json({ error: 'Заказ не найден' });
  res.json(order);
});

app.post('/api/orders', (req, res) => {
  const { productId, quantity } = req.body;
  if (!productId || !Number.isInteger(quantity) || quantity < 1) {
    return res.status(400).json({ error: 'Некорректные данные', fields: ['productId', 'quantity'] });
  }
  const order = { id: orders.length + 1, productId, quantity, status: 'new' };
  orders.push(order);
  res.status(201).location(`/api/orders/${order.id}`).json(order);
});

app.listen(3000);

Аутентификация

СпособКак работаетГде применяют
Сессия и cookieСервер хранит сессию, клиент — идентификаторКлассические веб-приложения
Токен JWTПодписанный токен со сведениями о пользователеSPA, мобильные приложения
API-ключПостоянный ключ в заголовкеМежсервисное взаимодействие
OAuth 2.0Доступ через сторонний провайдерВход через Google, ВК
JWT нельзя отозвать до истечения срока: он проверяется подписью, а не запросом к базе. Поэтому срок жизни делают коротким и выдают refresh-токен. Этот компромисс — хорошая тема для раздела о безопасности.

Документирование и тестирование

  1. Опишите API в формате OpenAPI (Swagger) — получите наглядную документацию и страницу для ручных проверок.
  2. В отчёт включите таблицу эндпоинтов: метод, путь, назначение, коды ответов.
  3. Приложите примеры запросов и ответов — по одному на каждый метод.
  4. Проверьте API через Postman или curl и вставьте снимки экрана.
  5. Опишите обработку ошибок: единый формат тела ответа при сбое.
curl -X POST http://localhost:3000/api/orders \
  -H 'Content-Type: application/json' \
  -d '{"productId": 42, "quantity": 3}' -i

curl 'http://localhost:3000/api/orders?status=new&page=1&limit=10'

Частые вопросы

Чем REST отличается от SOAP?

REST опирается на возможности самого HTTP и обменивается обычно JSON, SOAP — протокол поверх HTTP со строгой схемой XML. REST проще и легче, SOAP встречается в корпоративных и банковских интеграциях, где нужна жёсткая формализация.

Обязательно ли соблюдать все правила REST?

Полное соответствие требуется редко. Важнее последовательность: если во всём API действия выражены методами и одинаково устроены ошибки, работать с ним удобно. Смесь стилей вызывает больше замечаний, чем сознательное отклонение.

Что возвращать при удалении несуществующего объекта?

Строго — 404. Но многие API отвечают 204, считая операцию идемпотентной: результат в любом случае «объекта нет». Выберите вариант, зафиксируйте его в документации и придерживайтесь везде.

Читайте также

Сделаем работу по этой теме

Опишите задачу — ответим в течение 15 минут в личных сообщениях ВКонтакте, назовём срок и цену. Предоплаты за оценку нет.

  • Оценка заявки бесплатно
  • Правки по замечаниям преподавателя
  • Работы по всем техническим и IT-дисциплинам

Нажимая кнопку, вы соглашаетесь на обработку указанных данных для ответа на заявку.