← Назад к вопросам

Как используется http?

1.7 Middle🔥 191 комментариев
#REST API и HTTP

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

HTTP: Протокол передачи данных

HTTP (HyperText Transfer Protocol) — приложительный протокол на 7-м уровне OSI модели для передачи документов между клиентом и сервером. Основа веб-приложений.

HTTP методы (Verbs)

GET — получить ресурс без побочных эффектов

import requests

response = requests.get('https://api.example.com/users/123')
data = response.json()
# Безопасен, идемпотентен, кешируется

POST — создать новый ресурс

response = requests.post(
    'https://api.example.com/users',
    json={'name': 'John', 'email': 'john@example.com'}
)
user_id = response.json()['id']
# Не идемпотентен, каждый запрос создаёт новый ресурс

PUT — заменить ресурс целиком

response = requests.put(
    'https://api.example.com/users/123',
    json={'name': 'Jane', 'email': 'jane@example.com', 'age': 30}
)
# Идемпотентен, полная замена

PATCH — частичное обновление

response = requests.patch(
    'https://api.example.com/users/123',
    json={'email': 'newemail@example.com'}  # только email
)
# Обновляет только переданные поля

DELETE — удалить ресурс

response = requests.delete('https://api.example.com/users/123')
# Идемпотентен (повторный запрос тоже удачен)

HEAD — как GET, но без тела ответа

response = requests.head('https://api.example.com/users')
print(response.headers)  # только заголовки
# Для проверки доступности и метаданных

Коды состояния (Status Codes)

2xx — Success

  • 200 OK — успешный запрос
  • 201 Created — ресурс создан (POST)
  • 204 No Content — успешно, без тела ответа

3xx — Redirection

  • 301 Moved Permanently — ресурс переехал навсегда
  • 302 Found — временный редирект
  • 304 Not Modified — кеш валиден

4xx — Client Error

  • 400 Bad Request — неверный формат запроса
  • 401 Unauthorized — требуется аутентификация
  • 403 Forbidden — доступ запрещён
  • 404 Not Found — ресурс не найден
  • 409 Conflict — конфликт (например, дублирование)

5xx — Server Error

  • 500 Internal Server Error — ошибка сервера
  • 502 Bad Gateway — прокси-ошибка
  • 503 Service Unavailable — сервис недоступен

Структура HTTP запроса

GET /api/users/123 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123
Accept: application/json
User-Agent: MyApp/1.0

(пустая строка)
(тело запроса, если есть)
# В Python (requests)
response = requests.get(
    'https://api.example.com/users/123',
    headers={
        'Authorization': 'Bearer token123',
        'User-Agent': 'MyApp/1.0'
    },
    params={'filter': 'active'}  # Query string
)

Структура HTTP ответа

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 256
Cache-Control: max-age=3600
Set-Cookie: session=abc123

{"id": 123, "name": "John", "email": "john@example.com"}

REST API со статус-кодами

from fastapi import FastAPI, HTTPException, status

app = FastAPI()

@app.get("/users/{user_id}", status_code=200)
async def get_user(user_id: int):
    user = await find_user(user_id)
    if not user:
        raise HTTPException(
            status_code=404,
            detail="User not found"
        )
    return user

@app.post("/users", status_code=201)
async def create_user(user_data: UserSchema):
    new_user = await save_user(user_data)
    return new_user

@app.delete("/users/{user_id}", status_code=204)
async def delete_user(user_id: int):
    await delete_user_from_db(user_id)
    # Нет тела ответа для 204

HTTP версии

HTTP/1.1 — текущий стандарт, персистентные соединения

# Keep-Alive по умолчанию
response = requests.get('https://example.com')

HTTP/2 — мультиплексирование, сжатие заголовков, улучшение производительности

# Автоматически если сервер поддерживает
# requests библиотека может поддерживать через расширения

HTTP/3 — на базе QUIC, более быстрый

Кеширование

# Клиент
response = requests.get(
    'https://api.example.com/data',
    headers={'If-None-Match': 'etag123'}  # Условный запрос
)

if response.status_code == 304:  # Not Modified
    data = cache.get('data')
else:
    data = response.json()
    cache.set('data', data, etag=response.headers['ETag'])

# Сервер
from fastapi import Response, status

@app.get("/data")
async def get_data(if_none_match: str = Header(None)):
    current_etag = "etag123"
    if if_none_match == current_etag:
        return Response(status_code=304)
    return {"data": "value"}, 200, {"ETag": current_etag}

Content Negotiation

# Клиент указывает, что он может принять
response = requests.get(
    'https://api.example.com/users',
    headers={'Accept': 'application/json, application/xml'}
)

# Сервер выбирает подходящий формат
@app.get("/users")
async def get_users(accept: str = Header("application/json")):
    users = await get_all_users()
    if "xml" in accept:
        return convert_to_xml(users)
    return users  # JSON по умолчанию

Лучшие практики

Правильно используй HTTP методы — GET для чтения, POST для создания. Возвращай правильные статус-коды — помогает клиентам обрабатывать ошибки. Используй HTTPS всегда — защита данных в пути. Кешируй где возможно — улучшает производительность. Версионируй API — позволяет развиваться без ломания.