Введение
Термин «REST API» встречается в каждой вакансии разработчика, в каждой документации и в каждом техническом обсуждении. Но что это на самом деле? Если вы только начинаете путь в разработке или хотите раз и навсегда разобраться в теме — эта статья для вас.
Мы разберём REST API с нуля: от простых аналогий до реальных примеров кода. Без занудных определений из Википедии — только то, что вам действительно нужно знать для работы.
В этой статье вы узнаете:
- ✅ Что такое API и REST простыми словами
- ✅ 6 принципов REST-архитектуры
- ✅ Как устроен REST API-запрос на практике
- ✅ Примеры кода на JavaScript, Python и PHP
- ✅ Отличие REST от SOAP и GraphQL
- ✅ Как создать свой первый REST API
📋 Содержание
Что такое API
API (Application Programming Interface) — это набор правил, по которым одна программа может общаться с другой. API определяет, какие запросы можно отправить, в каком формате и какой ответ получить.
Аналогия: API — это официант в ресторане
Вы (клиент) хотите заказать еду. Кухня (сервер) готовит блюда. Но вы не ходите на кухню сами — вы общаетесь через официанта (API). Вы говорите ему, что хотите (запрос), он передаёт заказ кухне, и приносит вам блюдо (ответ).
API — это тот самый официант. Он знает меню (документацию), принимает заказы (запросы) и приносит блюда (ответы).
API окружают нас повсюду:
- Погодное приложение на телефоне → обращается к API метеосервиса
- Кнопка «Войти через Google» → обращается к API Google OAuth
- Оплата картой на сайте → обращается к API платёжной системы
- Курс валют в приложении банка → обращается к API ЦБ РФ
Что такое REST
REST (Representational State Transfer) — это архитектурный стиль, набор принципов для проектирования API. REST был описан Роем Филдингом в 2000 году в его докторской диссертации.
REST — это не технология, а стиль
REST — это не протокол, не библиотека и не фреймворк. Это набор правил и ограничений, которых придерживается API. Если API следует принципам REST — его называют RESTful API.
REST API — это API, построенный по принципам REST. Он использует:
- HTTP как протокол передачи данных
- URL для идентификации ресурсов
- HTTP методы (GET, POST, PUT, DELETE) для действий
- JSON (обычно) для формата данных
- HTTP статус коды для результата операции
GET /api/users → 200 OK + JSON
6 принципов REST
REST определяет 6 ограничений (constraints), которым должен следовать API, чтобы считаться RESTful.
1. Клиент-серверная архитектура (Client-Server)
Клиент и сервер разделены и развиваются независимо. Клиент не знает, как хранятся данные на сервере. Сервер не знает, как выглядит интерфейс клиента.
Пример: Один и тот же REST API обслуживает и веб-приложение на React, и мобильное приложение на Swift, и Telegram-бота на Python. Сервер для всех один — клиенты разные.
2. Отсутствие состояния (Stateless)
Каждый запрос содержит всю необходимую информацию для его обработки. Сервер не хранит состояние клиента между запросами. Нет «сессий» на сервере — каждый запрос автономен.
Пример: Токен авторизации передаётся в каждом запросе в заголовке Authorization, а не хранится в сессии на сервере.
3. Кэширование (Cacheable)
Ответы сервера должны явно указывать, можно ли их кэшировать. Кэширование снижает нагрузку на сервер и ускоряет ответы для клиента.
Пример: GET-запрос к /api/products может возвращать заголовок Cache-Control: max-age=3600 — данные можно кэшировать на час.
4. Единообразный интерфейс (Uniform Interface)
Все ресурсы доступны через единообразные URL. Действия определяются HTTP методами. Формат данных описан в заголовках. Это главный принцип REST.
- Ресурсы идентифицируются по URL:
/api/users/42 - Действие определяет HTTP метод: GET, POST, PUT, DELETE
- Формат данных указан в
Content-Type
5. Многоуровневая система (Layered System)
Между клиентом и сервером могут быть промежуточные слои: балансировщик нагрузки, CDN, кэширующий прокси, API Gateway. Клиент не знает (и не должен знать) о промежуточных слоях.
6. Код по запросу (Code on Demand) — необязательный
Сервер может передавать клиенту исполняемый код (JavaScript). Это единственный необязательный принцип REST, и на практике он используется редко.
Анатомия REST-запроса
Каждый REST-запрос состоит из нескольких частей. Разберём реальный пример:
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...
Accept: application/json
{
"name": "Иван Петров",
"email": "ivan@example.com",
"role": "developer"
}
| Часть | Значение | Описание |
|---|---|---|
| Метод | POST |
Что делаем (создаём ресурс) |
| URL (endpoint) | /api/users |
К какому ресурсу обращаемся |
| Заголовки | Content-Type, Authorization |
Метаинформация: формат, авторизация |
| Тело (body) | JSON-объект | Данные для создания пользователя |
А вот как выглядит ответ:
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/users/43
{
"id": 43,
"name": "Иван Петров",
"email": "ivan@example.com",
"role": "developer",
"created_at": "2026-02-23T10:30:00Z"
}
| Часть ответа | Значение | Описание |
|---|---|---|
| Статус код | 201 Created |
Результат: ресурс создан |
| Заголовки | Location, Content-Type |
URL нового ресурса, формат ответа |
| Тело | JSON-объект | Созданный пользователь с присвоенным ID |
Ресурсы и URL
В REST всё является ресурсом. Ресурс — это любая сущность, к которой можно обратиться по URL: пользователь, статья, товар, заказ, файл.
Правила формирования URL
| Правило | Хорошо | Плохо |
|---|---|---|
| Существительные, не глаголы | /api/users |
/api/getUsers |
| Множественное число | /api/articles |
/api/article |
| Строчные буквы | /api/user-roles |
/api/UserRoles |
| Дефис для разделения | /api/order-items |
/api/order_items |
| Вложенность для связей | /api/users/42/posts |
/api/getUserPosts?id=42 |
Примеры типичных endpoint'ов
GET /api/users — список пользователей
GET /api/users/42 — пользователь #42
POST /api/users — создать пользователя
PUT /api/users/42 — заменить пользователя #42
PATCH /api/users/42 — обновить поля пользователя #42
DELETE /api/users/42 — удалить пользователя #42
GET /api/users/42/posts — посты пользователя #42
POST /api/users/42/posts — создать пост от пользователя #42
GET /api/products?category=electronics&sort=price&page=2
JSON — формат данных
JSON (JavaScript Object Notation) — стандартный формат обмена данными в REST API. Он компактный, читаемый и поддерживается всеми языками программирования.
{
"id": 42,
"name": "Иван Петров",
"email": "ivan@example.com",
"is_active": true,
"roles": ["developer", "admin"],
"address": {
"city": "Москва",
"country": "Россия"
},
"created_at": "2026-02-23T10:30:00Z"
}
Почему JSON, а не XML?
- Компактнее — JSON-ответ в 2–3 раза легче XML
- Читабельнее — нет закрывающих тегов и атрибутов
- Нативный для JavaScript —
JSON.parse()встроен в язык - Быстрее парсить — меньше накладных расходов
Примеры запросов на трёх языках
Рассмотрим полный CRUD (создание, чтение, обновление, удаление) на реальных примерах.
JavaScript (fetch API)
const API_URL = 'https://api.example.com';
// GET — список пользователей
async function getUsers() {
const response = await fetch(`${API_URL}/users`);
const users = await response.json();
console.log(users);
return users;
}
// GET — один пользователь
async function getUser(id) {
const response = await fetch(`${API_URL}/users/${id}`);
if (response.status === 404) {
console.error('Пользователь не найден');
return null;
}
return await response.json();
}
// POST — создать пользователя
async function createUser(name, email) {
const response = await fetch(`${API_URL}/users`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, email })
});
if (response.status === 201) {
const newUser = await response.json();
console.log('Создан:', newUser);
return newUser;
}
}
// PATCH — обновить email
async function updateEmail(id, newEmail) {
const response = await fetch(`${API_URL}/users/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: newEmail })
});
return await response.json();
}
// DELETE — удалить пользователя
async function deleteUser(id) {
const response = await fetch(`${API_URL}/users/${id}`, {
method: 'DELETE'
});
return response.status === 204;
}
Python (requests)
import requests
API_URL = 'https://api.example.com'
# GET — список
users = requests.get(f'{API_URL}/users').json()
print(users)
# GET — один пользователь
response = requests.get(f'{API_URL}/users/42')
if response.status_code == 200:
user = response.json()
print(user)
elif response.status_code == 404:
print('Пользователь не найден')
# POST — создать
response = requests.post(f'{API_URL}/users', json={
'name': 'Иван Петров',
'email': 'ivan@example.com'
})
if response.status_code == 201:
new_user = response.json()
print(f'Создан пользователь ID: {new_user["id"]}')
# PATCH — обновить
response = requests.patch(f'{API_URL}/users/42', json={
'email': 'new@example.com'
})
# DELETE — удалить
response = requests.delete(f'{API_URL}/users/42')
if response.status_code == 204:
print('Удалено')
PHP (cURL)
<?php
$apiUrl = 'https://api.example.com';
// GET — список пользователей
$ch = curl_init("$apiUrl/users");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$users = json_decode($response, true);
curl_close($ch);
// POST — создать пользователя
$ch = curl_init("$apiUrl/users");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Иван Петров',
'email' => 'ivan@example.com',
]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($statusCode === 201) {
$newUser = json_decode($response, true);
echo "Создан: ID {$newUser['id']}\n";
}
// PATCH — обновить
$ch = curl_init("$apiUrl/users/42");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => json_encode(['email' => 'new@example.com']),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
$response = curl_exec($ch);
curl_close($ch);
// DELETE — удалить
$ch = curl_init("$apiUrl/users/42");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
]);
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($statusCode === 204) {
echo "Пользователь удалён\n";
}
REST vs SOAP
До REST доминировал SOAP (Simple Object Access Protocol). Сравним оба подхода:
| Характеристика | REST | SOAP |
|---|---|---|
| Формат данных | JSON, XML, любой | Только XML |
| Протокол | HTTP | HTTP, SMTP, TCP |
| Стандарт | Архитектурный стиль | Строгий протокол (W3C) |
| Размер сообщений | Компактный (JSON) | Тяжёлый (XML + Envelope) |
| Кэширование | Встроенное (HTTP Cache) | Не поддерживается |
| Скорость | Быстрее | Медленнее |
| Документация | OpenAPI / Swagger | WSDL |
| Применение | Веб-приложения, мобильные | Enterprise, банки, госсистемы |
✅ REST — когда выбирать
- Веб и мобильные приложения
- Публичные API
- Микросервисы
- Нужна скорость и простота
- Кэширование важно
❌ SOAP — когда выбирать
- Банковские и финансовые системы
- Нужна строгая типизация (WSDL)
- Требуется WS-Security
- Legacy-интеграции
- Транзакции между сервисами
REST vs GraphQL
GraphQL — это язык запросов к API, разработанный Facebook в 2015 году. Он решает некоторые проблемы REST, но добавляет свои.
Главная проблема REST, которую решает GraphQL
Over-fetching и under-fetching:
// REST: нужно имя и email пользователя и названия его постов
// Запрос 1: получаем пользователя (+ лишние поля: age, avatar, settings...)
GET /api/users/42
// Запрос 2: получаем его посты (+ лишние поля: content, likes, comments...)
GET /api/users/42/posts
// GraphQL: один запрос — только нужные данные
query {
user(id: 42) {
name
email
posts {
title
}
}
}
| Характеристика | REST | GraphQL |
|---|---|---|
| Endpoint'ы | Множество (/users, /posts, ...) |
Один (/graphql) |
| Клиент выбирает поля | Нет (сервер решает) | Да (запрос определяет) |
| Кэширование | Простое (HTTP Cache) | Сложное |
| Типизация | Нет (нужен OpenAPI) | Встроенная схема |
| Загрузка файлов | Простая | Сложная |
| Порог входа | Низкий | Средний |
| Инструменты | Postman, cURL, Swagger | GraphiQL, Apollo Studio |
Когда что выбрать?
- REST — простые CRUD-операции, публичные API, микросервисы, когда важно кэширование
- GraphQL — сложные связи между данными, мобильные приложения (экономия трафика), когда клиент должен контролировать структуру ответа
- Оба — многие компании используют REST для простых операций и GraphQL для сложных запросов
Как создать свой первый REST API
Рассмотрим минимальный пример REST API на Node.js (Express) — 30 строк кода:
const express = require('express');
const app = express();
app.use(express.json());
let users = [
{ id: 1, name: 'Иван', email: 'ivan@example.com' },
{ id: 2, name: 'Мария', email: 'maria@example.com' },
];
let nextId = 3;
// GET /api/users — список
app.get('/api/users', (req, res) => {
res.json(users);
});
// GET /api/users/:id — один пользователь
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ error: 'Не найден' });
res.json(user);
});
// POST /api/users — создать
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'name и email обязательны' });
}
const user = { id: nextId++, name, email };
users.push(user);
res.status(201).json(user);
});
// PATCH /api/users/:id — обновить
app.patch('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ error: 'Не найден' });
Object.assign(user, req.body);
res.json(user);
});
// DELETE /api/users/:id — удалить
app.delete('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === parseInt(req.params.id));
if (index === -1) return res.status(404).json({ error: 'Не найден' });
users.splice(index, 1);
res.status(204).send();
});
app.listen(3000, () => console.log('API запущен на порту 3000'));
Запустите и проверьте:
# Установить Express
npm init -y && npm install express
# Запустить сервер
node server.js
# Проверить в другом терминале
curl http://localhost:3000/api/users
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"name": "Алексей", "email": "alex@test.ru"}'
⚠️ Не хотите писать бэкенд?
Если вам нужен REST API для тестирования или прототипирования, но вы не хотите поднимать сервер — используйте Mock API. Сервисы вроде LightBox API позволяют создать полноценный REST API за 2 минуты через веб-интерфейс, без единой строчки серверного кода.
Best Practices проектирования REST API
✅ Правила хорошего REST API
- Используйте существительные в URL —
/api/users, не/api/getUsers - Возвращайте правильные HTTP коды — 201 для создания, 204 для удаления, 4xx для ошибок клиента
- Версионируйте API —
/api/v1/users,/api/v2/users - Поддерживайте фильтрацию и пагинацию —
?page=2&limit=20&sort=name - Возвращайте понятные ошибки — с кодом, сообщением и деталями
- Документируйте API — используйте OpenAPI (Swagger)
Формат ошибок — единый стандарт
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Ошибка валидации данных",
"details": [
{ "field": "email", "message": "Некорректный формат email" },
{ "field": "name", "message": "Имя обязательно для заполнения" }
]
}
}
Пагинация — два подхода
// Offset-based (классическая)
GET /api/users?page=2&limit=20
{
"data": [...],
"pagination": {
"page": 2,
"limit": 20,
"total": 150,
"total_pages": 8
}
}
// Cursor-based (для больших наборов данных)
GET /api/users?cursor=eyJpZCI6NDJ9&limit=20
{
"data": [...],
"pagination": {
"next_cursor": "eyJpZCI6NjJ9",
"has_more": true
}
}
❌ Антипаттерны REST API
- Глаголы в URL —
/api/createUser,/api/deletePost - GET для изменений —
GET /api/users/42/delete - 200 для ошибок —
200 OK → {"error": "not found"} - Отсутствие версионирования — ломающие изменения без предупреждения
- Непоследовательность —
/api/users,/api/getArticle,/api/product_list
FAQ
❓ Чем REST API отличается от обычного API?
Ответ: API — это общее понятие интерфейса для взаимодействия программ. REST API — это конкретный архитектурный стиль построения API, основанный на принципах REST: клиент-серверная архитектура, отсутствие состояния (stateless), единообразный интерфейс, кэширование. Не каждый API — RESTful, но большинство современных веб-API следуют принципам REST.
❓ Что лучше: REST или GraphQL?
Ответ: Зависит от задачи.
- REST — для простых CRUD-операций, публичных API, микросервисов, кэширования
- GraphQL — для сложных связей между данными, мобильных приложений (экономия трафика), когда клиент управляет структурой ответа
Многие компании используют оба подхода одновременно: REST для простых операций, GraphQL для сложных запросов.
❓ Обязательно ли REST API возвращает JSON?
Ответ: Нет. REST не привязан к формату данных. API может возвращать JSON, XML, YAML, HTML, CSV или Protocol Buffers. Но JSON стал стандартом де-факто благодаря компактности, читаемости и нативной поддержке в JavaScript. Формат данных указывается в заголовках Content-Type и Accept.
❓ Можно ли сделать REST API без бэкенда?
Ответ: Да! Для этого существуют Mock API сервисы. Они позволяют создать полноценный REST API с нужными endpoint'ами, HTTP методами и ответами — без написания серверного кода. Это полезно для:
- Прототипирования — быстро показать, как будет работать приложение
- Параллельной разработки — frontend работает, пока backend ещё не готов
- Тестирования — проверить обработку ошибок и edge cases
- Обучения — попрактиковаться с REST API без настройки сервера
Заключение
📝 Ключевые тезисы
| Понятие | Простое объяснение |
|---|---|
| API | Интерфейс для общения программ между собой |
| REST | Набор правил для проектирования API |
| Ресурс | Любая сущность с уникальным URL (/api/users/42) |
| HTTP методы | Действия с ресурсом: GET (читать), POST (создать), PUT/PATCH (обновить), DELETE (удалить) |
| Статус коды | Результат операции: 200 (ОК), 404 (не найден), 500 (ошибка сервера) |
| JSON | Стандартный формат данных в REST API |
| Stateless | Каждый запрос содержит всю информацию для обработки |
REST API — это стандарт современной веб-разработки. Понимание REST-принципов позволит вам проектировать API, которые легко использовать, тестировать и масштабировать. Начните с простых CRUD-операций, соблюдайте конвенции — и ваш API будет понятен любому разработчику.
💡 Что делать дальше?
- Попрактикуйтесь — создайте простой REST API на своём стеке
- Изучите OpenAPI/Swagger — для документирования API
- Прочитайте про HTTP методы и HTTP статус коды — наши подробные руководства
- Попробуйте Mock API — для быстрого прототипирования
🎯 Создайте свой REST API за 2 минуты
Хотите попрактиковаться с REST API, но не хотите поднимать сервер?
LightBox API — это Mock API сервис, с которым вы создадите полноценный REST API через веб-интерфейс: endpoint'ы, HTTP методы, статус коды, JSON-ответы — всё без единой строчки серверного кода.
- ✓ Все HTTP методы (GET, POST, PUT, PATCH, DELETE)
- ✓ Настраиваемые статус коды и ответы
- ✓ Импорт Swagger/OpenAPI за 2 минуты
- ✓ Логирование всех запросов
- ✓ Бесплатный план для старта
Статья опубликована: 23 февраля 2026
Автор: LightBox API Team