Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Вокруг чего работает REST API
Основной принцип
REST API работает вокруг РЕСУРСОВ — сущностей, которыми можно манипулировать через стандартные HTTP операции.
Вместо глаголов (действий):
/api/createUser
/api/deleteUser
/api/updateUser
REST использует существительные (ресурсы) + HTTP методы:
/api/users (GET, POST, PUT, DELETE)
Четыре ключевых концепции REST
1. Ресурсы (Resources)
# Ресурсы — это сущности в системе
# Users — ресурс
GET /api/users # Получить всех пользователей
GET /api/users/42 # Получить пользователя с ID 42
POST /api/users # Создать нового пользователя
PUT /api/users/42 # Обновить пользователя 42
DELETE /api/users/42 # Удалить пользователя 42
# Posts — другой ресурс
GET /api/posts # Все посты
POST /api/posts # Создать пост
# Comments — подресурс
GET /api/posts/1/comments # Комментарии поста 1
POST /api/posts/1/comments # Добавить комментарий к посту 1
2. HTTP методы (Verbs)
GET — читать данные (безопасно, идемпотентно)
POST — создавать новые ресурсы
PUT — полностью заменять ресурс
PATCH — частично обновлять ресурс
DELETE — удалять ресурс
HEAD — как GET, но без тела ответа
OPTIONS — получить доступные методы
3. Представления (Representations)
# Один ресурс может быть представлен по-разному
# JSON представление
GET /api/users/42
Accept: application/json
Response:
{
"id": 42,
"name": "Alice",
"email": "alice@example.com"
}
# XML представление
GET /api/users/42
Accept: application/xml
Response:
<?xml version="1.0"?>
<user>
<id>42</id>
<name>Alice</name>
<email>alice@example.com</email>
</user>
# Клиент говорит серверу, в каком формате ему нужен ресурс
4. Stateless коммуникация
# Каждый запрос содержит всю нужную информацию
# Сервер не хранит контекст клиента между запросами
# ❌ Неправильно — зависит от сессии
GET /api/orders
# Результат зависит от текущей сессии пользователя
# ✅ Правильно — всё в запросе
GET /api/users/42/orders
Authorization: Bearer token123
# Сервер получает всю информацию для ответа
Практические примеры
REST API для блога
# FastAPI
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
# Модель ресурса
class Post(BaseModel):
title: str
content: str
author_id: int
# Базы данных (в памяти для примера)
posts = {}
post_counter = 0
# CREATE — создание нового ресурса
@app.post("/api/posts") # POST /api/posts
def create_post(post: Post):
global post_counter
post_counter += 1
posts[post_counter] = post
return {"id": post_counter, **post.dict()}
# READ — получение ресурса
@app.get("/api/posts/{post_id}") # GET /api/posts/1
def get_post(post_id: int):
if post_id not in posts:
raise HTTPException(status_code=404, detail="Post not found")
return {"id": post_id, **posts[post_id].dict()}
# READ LIST — получение всех ресурсов
@app.get("/api/posts") # GET /api/posts
def list_posts():
return [{"id": pid, **p.dict()} for pid, p in posts.items()]
# UPDATE — обновление ресурса
@app.put("/api/posts/{post_id}") # PUT /api/posts/1
def update_post(post_id: int, post: Post):
if post_id not in posts:
raise HTTPException(status_code=404, detail="Post not found")
posts[post_id] = post
return {"id": post_id, **post.dict()}
# DELETE — удаление ресурса
@app.delete("/api/posts/{post_id}") # DELETE /api/posts/1
def delete_post(post_id: int):
if post_id not in posts:
raise HTTPException(status_code=404, detail="Post not found")
del posts[post_id]
return {"message": "Post deleted"}
Django REST Framework пример
from rest_framework import viewsets
from rest_framework.decorators import action
from .serializers import UserSerializer
from .models import User
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
# Автоматически создаёт:
# GET /api/users/ (list)
# POST /api/users/ (create)
# GET /api/users/{id}/ (retrieve)
# PUT /api/users/{id}/ (update)
# DELETE /api/users/{id}/ (destroy)
@action(detail=True, methods=['post'])
def set_password(self, request, pk=None):
# Кастомное действие
# POST /api/users/{id}/set_password/
user = self.get_object()
user.set_password(request.data['password'])
user.save()
return Response({'status': 'password set'})
Важные принципы REST
1. Ресурсы идентифицируются URL
Каждый ресурс имеет уникальный адрес:
/api/users/42 — конкретный пользователь
/api/posts/1/comments/5 — комментарий 5 к посту 1
/api/products/abc123 — продукт с ID abc123
2. Стандартные HTTP коды ответа
# 2xx — Успех
200 OK — Запрос успешен
201 Created — Ресурс создан
204 No Content — Успех, но нет тела ответа
# 4xx — Ошибка клиента
400 Bad Request — Неверные данные
401 Unauthorized — Нужна авторизация
403 Forbidden — Доступ запрещён
404 Not Found — Ресурс не найден
409 Conflict — Конфликт (например, дубликат)
# 5xx — Ошибка сервера
500 Internal Error — Ошибка на сервере
503 Service Unavailable — Сервис недоступен
3. Методы безопасны и идемпотентны
Bезопасные методы (не меняют состояние):
GET, HEAD, OPTIONS
Идемпотентные методы (один результат при повторении):
GET, PUT, DELETE
Небезопасные и неидемпотентные:
POST (создаёт новый ресурс каждый раз)
Вложенные ресурсы
# Правильно — вложенные ресурсы
GET /api/users/42/posts # Посты пользователя 42
GET /api/users/42/posts/1 # Пост 1 пользователя 42
GET /api/posts/1/comments # Комментарии поста 1
POST /api/posts/1/comments # Добавить комментарий к посту 1
# Неправильно — глубокая вложенность
GET /api/users/42/posts/1/comments/5/author/10 # Слишком глубоко
# Альтернатива
GET /api/comments/5 # Прямой доступ к комментарию
Фильтрация, сортировка, пагинация
# Фильтрация через query параметры
GET /api/users?role=admin # Только администраторы
GET /api/posts?author_id=42 # Посты автора 42
GET /api/products?price_min=100&price_max=500
# Сортировка
GET /api/posts?sort=created_at # По дате создания
GET /api/posts?sort=-created_at # По дате, убывающе
# Пагинация
GET /api/posts?page=1&limit=10 # Первая страница, 10 элементов
GET /api/posts?offset=20&limit=10 # Начиная с элемента 20
# Выборка полей
GET /api/users?fields=id,name,email # Только нужные поля
Версионирование API
# Вариант 1: URL версионирование
GET /api/v1/users
GET /api/v2/users # Другая версия
# Вариант 2: Header версионирование
GET /api/users
Accept: application/vnd.myapp.v2+json
# Вариант 3: Query параметр
GET /api/users?api_version=2
Ошибки при проектировании REST API
# ❌ Неправильно — глаголы в URL
GET /api/getUser # Глагол не нужен
POST /api/createUser # Используй HTTP метод
GET /api/deleteUser?id=42 # DELETE уже есть
# ✅ Правильно — только существительные
GET /api/users # Получить
POST /api/users # Создать
GET /api/users/42 # Получить конкретного
DELETE /api/users/42 # Удалить
# ❌ Неправильно — статус в теле ответа
{
"status": "error",
"httpCode": 200 # Противоречие!
}
# ✅ Правильно — статус в HTTP коде
HTTP 400 Bad Request
{
"error": "Invalid input"
}
REST vs RPC
# RPC стиль (старый подход)
POST /api/user.get?id=42
POST /api/user.create
POST /api/user.delete?id=42
# REST стиль (правильный)
GET /api/users/42
POST /api/users
DELETE /api/users/42
# Различие:
# RPC — акцент на действия (функции)
# REST — акцент на ресурсы
Best Practice
# 1. Используй существительные во множественном числе
GET /api/users # не /api/user
GET /api/products # не /api/product
# 2. Используй иерархию для вложенных ресурсов
GET /api/users/42/posts # Посты пользователя 42
GET /api/posts/1/comments # Комментарии поста 1
# 3. Используй стандартные HTTP коды
200 OK для успеха
201 Created для создания
400 Bad Request для ошибок клиента
500 Internal Server Error для ошибок сервера
# 4. Версионируй API
/api/v1/users # Первая версия
/api/v2/users # Вторая версия
# 5. Документируй API
# Используй Swagger/OpenAPI
# 6. Возвращай JSON (стандарт)
# XML устаревший