Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что должно входить во фреймворк
Это важный вопрос архитектуры. За 10+ лет я видел фреймворки, которые делали слишком много (монолиты) и слишком мало (пусто). Вот мой список обязательных компонентов.
Ядро фреймворка (ОБЯЗАТЕЛЬНО)
1. HTTP Router и Request/Response handling
# Это основа всего
from framework import Framework, Request, Response
app = Framework()
@app.route("/api/users", methods=["GET", "POST"])
def handle_users(request: Request) -> Response:
if request.method == "GET":
users = get_users()
return Response(json=users, status=200)
else:
user = create_user(request.json)
return Response(json=user, status=201)
# Параметры, query строки, все должно работать
@app.route("/api/users/<int:user_id>")
def get_user(request: Request, user_id: int) -> Response:
user = find_user(user_id)
if not user:
return Response(json={"error": "Not found"}, status=404)
return Response(json=user)
2. Middleware система
# Для логирования, аутентификации, CORS, и т.д.
class AuthMiddleware:
def __call__(self, request: Request, next):
token = request.headers.get("Authorization")
if not token:
return Response(json={"error": "Unauthorized"}, status=401)
request.user = verify_token(token)
return next(request)
class LoggingMiddleware:
def __call__(self, request: Request, next):
start = time.time()
response = next(request)
duration = time.time() - start
logger.info(f"{request.method} {request.path} - {response.status} ({duration:.2f}s)")
return response
app.use(LoggingMiddleware())
app.use(AuthMiddleware())
3. Обработка ошибок
# Exception handling должен быть встроен
class HTTPException(Exception):
def __init__(self, status: int, detail: str):
self.status = status
self.detail = detail
@app.error_handler(HTTPException)
def handle_http_error(error: HTTPException) -> Response:
return Response(
json={"error": error.detail},
status=error.status
)
@app.error_handler(ValueError)
def handle_value_error(error: ValueError) -> Response:
logger.error(f"Validation error: {error}")
return Response(
json={"error": "Invalid data"},
status=400
)
Важные компоненты (ДОЛЖНЫ БЫТЬ)
4. Типизация и валидация
# Фреймворк должен поддерживать типизацию
from framework import Schema
class UserSchema(Schema):
id: int
name: str
email: str
age: int
# Автоматическая валидация
@app.route("/api/users", methods=["POST"])
def create_user(request: Request) -> Response:
# Автоматически парсит и валидирует
user_data = UserSchema(**request.json)
user = save_user(user_data)
return Response(json=user, status=201)
5. Dependency Injection
# DI должен быть встроен
class UserRepository:
def get(self, user_id: int):
return db.query(User).get(user_id)
class UserService:
def __init__(self, repo: UserRepository):
self.repo = repo
def find_user(self, user_id: int):
return self.repo.get(user_id)
# Фреймворк внедряет зависимости автоматически
@app.route("/api/users/<int:user_id>")
def get_user(request: Request, service: UserService, user_id: int):
user = service.find_user(user_id)
return Response(json=user)
6. Логирование
# Встроенное логирование на разных уровнях
from framework import logger
@app.route("/api/action")
def action(request: Request):
logger.debug("Processing action")
try:
result = do_something()
logger.info(f"Action completed: {result}")
return Response(json=result)
except Exception as e:
logger.error(f"Action failed: {e}")
raise
7. Конфигурация
# Управление конфигурацией (dev/test/prod)
class Config:
DEBUG = False
DATABASE_URL = "postgresql://..."
SECRET_KEY = "secret"
class DevelopmentConfig(Config):
DEBUG = True
DATABASE_URL = "sqlite:///dev.db"
app = Framework(config=DevelopmentConfig())
Полезные компоненты (МОЖНО ДОБАВИТЬ)
8. CORS и безопасность
class CORSMiddleware:
def __call__(self, request: Request, next):
response = next(request)
response.headers["Access-Control-Allow-Origin"] = "*"
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE"
return response
app.use(CORSMiddleware())
9. Кэширование
class Cache:
def get(self, key: str):
pass
def set(self, key: str, value, ttl: int):
pass
def delete(self, key: str):
pass
# Использование
from framework import cache
@app.route("/api/expensive")
def expensive_operation(request: Request):
cached = cache.get("expensive_result")
if cached:
return Response(json=cached)
result = compute_expensive()
cache.set("expensive_result", result, ttl=3600)
return Response(json=result)
10. Pagination и filtering
class Paginator:
def __init__(self, page: int = 1, per_page: int = 20):
self.page = page
self.per_page = per_page
def paginate(self, query):
offset = (self.page - 1) * self.per_page
return query.limit(self.per_page).offset(offset)
@app.route("/api/items")
def list_items(request: Request):
page = request.query.get("page", 1, type=int)
per_page = request.query.get("per_page", 20, type=int)
paginator = Paginator(page, per_page)
items = paginator.paginate(db.query(Item))
return Response(json=items)
Чего НЕ должно быть во фреймворке
❌ ORM (слишком специфично)
# Фреймворк не должен навязывать ORM
# SQLAlchemy, Tortoise, Peewee — выбор пользователя
# Фреймворк просто предоставляет интеграцию
❌ WebSocket (можно добавить, но опционально)
# Не все приложения нужны WebSockets
# Должны быть добавлены как опция, не обязательно
❌ GraphQL (слишком специфично)
# GraphQL — выбор архитектуры, не фреймворка
# REST/GraphQL независимы от фреймворка
❌ Встроенная база данных (слишком специфично)
# Пусть пользователь выбирает PostgreSQL, MongoDB, Redis
# Фреймворк просто предоставляет адаптеры
Архитектура фреймворка
# Мой идеальный фреймворк (минималистичный)
from framework import Framework, Request, Response, Middleware
from framework.di import Container
from framework.log import Logger
from framework.config import Config
class MyFramework(Framework):
def __init__(self, config: Config):
self.config = config
self.logger = Logger(config.log_level)
self.container = Container() # DI
self.middleware = [] # Middleware chain
self.routes = {} # Route registry
def use(self, middleware: Middleware) -> None:
"""Register middleware"""
self.middleware.append(middleware)
def route(self, path: str, methods: list = None) -> callable:
"""Register route"""
def decorator(handler):
self.routes[path] = (methods or ["GET"], handler)
return handler
return decorator
def handle(self, request: Request) -> Response:
"""Main request handling"""
# Apply middleware
for mw in self.middleware:
request = mw.before(request)
# Route to handler
handler = self.find_handler(request.path, request.method)
response = handler(request)
# Apply response middleware
for mw in reversed(self.middleware):
response = mw.after(response)
return response
Практический пример
# Минимальный фреймворк, готовый к production
app = Framework()
class Database:
def get_user(self, user_id: int):
# Реальный запрос
pass
app.container.register(Database, singleton=True)
@app.route("/api/users/<int:user_id>")
def get_user(request: Request, db: Database, user_id: int):
user = db.get_user(user_id)
return Response(json=user, status=200 if user else 404)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
Мой вывод
Хороший фреймворк должен быть:
- Минималистичным — только необходимое
- Расширяемым — легко добавлять компоненты
- Независимым — не навязывает конкретные технологии (ORM, БД)
- Type-safe — поддерживает типизацию
- Хорошо документированным — примеры и лучшие практики
Примеры хороших фреймворков:
- FastAPI — минимален, но мощный
- Flask — простой и расширяемый
- Django — полнофункциональный (может быть избыточным)
- Starlette — низкоуровневый, очень контролируемый