Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
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 — позволяет развиваться без ломания.