Разработка серверной части (Backend) для мобильного приложения на Python (Django/FastAPI)
Python — второй по популярности язык для мобильных бэкендов после Node.js. Две доминирующие опции: Django REST Framework — batteries-included, ORM, admin, auth из коробки; FastAPI — асинхронный, типобезопасный, быстрый старт. Выбор между ними зависит от требований к скорости разработки, производительности и размера команды.
FastAPI: когда нужна скорость и типизация
FastAPI строится на Pydantic и Starlette. Каждый endpoint автоматически валидирует входные данные через аннотации типов и генерирует OpenAPI-документацию:
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel, UUID4
from sqlalchemy.ext.asyncio import AsyncSession
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/token")
class CreatePostRequest(BaseModel):
title: str
content: str
author_id: UUID4
class PostResponse(BaseModel):
id: UUID4
title: str
content: str
created_at: datetime
class Config:
from_attributes = True
@app.post("/posts", response_model=PostResponse, status_code=201)
async def create_post(
body: CreatePostRequest,
db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user),
):
if body.author_id != current_user.id:
raise HTTPException(status_code=403, detail="Forbidden")
post = await post_service.create(db, body)
return post
Pydantic v2 (Rust-based) валидирует данные быстрее, чем большинство альтернатив. response_model автоматически сериализует ORM-объект и скрывает поля, которых нет в схеме (например, пароль-хеш не попадёт в ответ).
SQLAlchemy 2.x + AsyncSession для асинхронной работы с PostgreSQL через asyncpg:
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
engine = create_async_engine(settings.DATABASE_URL) # postgresql+asyncpg://...
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
async def get_db():
async with AsyncSessionLocal() as session:
yield session
Alembic для миграций схемы БД — генерирует diff между моделями и текущей БД.
Аутентификация JWT
from jose import JWTError, jwt
from datetime import datetime, timedelta
def create_access_token(user_id: str) -> str:
expires = datetime.utcnow() + timedelta(minutes=15)
return jwt.encode(
{"sub": user_id, "exp": expires, "type": "access"},
settings.JWT_SECRET,
algorithm="HS256",
)
async def get_current_user(
token: str = Depends(oauth2_scheme),
db: AsyncSession = Depends(get_db),
) -> User:
try:
payload = jwt.decode(token, settings.JWT_SECRET, algorithms=["HS256"])
user_id: str = payload.get("sub")
except JWTError:
raise HTTPException(status_code=401, detail="Could not validate token")
user = await user_repo.get(db, user_id)
if not user:
raise HTTPException(status_code=401, detail="User not found")
return user
Django REST Framework: когда нужен полный стек
DRF выигрывает когда нужно быстро получить admin-панель, богатый ORM с select_related/prefetch_related, встроенные permissions и throttling:
# serializers.py
class PostSerializer(serializers.ModelSerializer):
author_name = serializers.SerializerMethodField()
class Meta:
model = Post
fields = ['id', 'title', 'content', 'author_name', 'created_at']
read_only_fields = ['id', 'created_at']
def get_author_name(self, obj):
return obj.author.get_full_name()
# views.py
class PostViewSet(ModelViewSet):
serializer_class = PostSerializer
permission_classes = [IsAuthenticated]
throttle_classes = [UserRateThrottle]
def get_queryset(self):
return Post.objects.filter(author=self.request.user)\
.select_related('author')\
.order_by('-created_at')
select_related решает N+1 проблему: один SQL JOIN вместо запроса для каждого автора. prefetch_related — для many-to-many.
django-channels для WebSocket (чат, realtime). Celery + Redis для фоновых задач (отправка email, пуш-уведомлений, тяжёлые вычисления).
# tasks.py
from celery import shared_task
import firebase_admin.messaging as fcm
@shared_task(bind=True, max_retries=3, default_retry_delay=60)
def send_push_notification(self, token: str, title: str, body: str):
try:
message = fcm.Message(
token=token,
notification=fcm.Notification(title=title, body=body),
android=fcm.AndroidConfig(priority='high'),
apns=fcm.APNSConfig(payload=fcm.APNSPayload(aps=fcm.Aps(sound='default'))),
)
fcm.send(message)
except Exception as exc:
raise self.retry(exc=exc)
Сравнение подходов
| Критерий | FastAPI | Django REST Framework |
|---|---|---|
| Async из коробки | Да (asyncio) | Частично (Django 4.1+) |
| Скорость запуска | Высокая | Средняя |
| Admin-панель | Нет (сторонние) | Встроенная |
| ORM | SQLAlchemy / Tortoise | Django ORM |
| Документация API | Автогенерация (Swagger) | drf-spectacular |
| Подходит для | Новые проекты, API-only | Быстрый MVP с admin |
Типичная проблема: синхронный код в async FastAPI
# Плохо: блокирует event loop
@app.get("/data")
async def get_data():
return requests.get("https://external-api.com/data").json() # sync!
# Хорошо
@app.get("/data")
async def get_data():
async with httpx.AsyncClient() as client:
response = await client.get("https://external-api.com/data")
return response.json()
requests в async def блокирует весь event loop: все параллельные запросы встают в очередь. httpx.AsyncClient — асинхронная альтернатива.
Развёртывание
FastAPI/Django запускается через Uvicorn + Gunicorn (несколько воркеров × async). Docker с многоэтапной сборкой для минимального образа. Nginx как reverse proxy. PostgreSQL + Redis в docker-compose для локала, RDS + ElastiCache для AWS.
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
CMD ["gunicorn", "app.main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000"]
Что входит в разработку
Проектирование API под требования мобильного клиента. Настройка PostgreSQL + Alembic миграции. Auth (JWT). CRUD-модули. Push-уведомления (Firebase Admin SDK). Фоновые задачи (Celery). Docker + CI/CD. Документация OpenAPI.
Сроки
MVP (Auth + 3–5 ресурсов): 2–3 недели. Полноценный бэкенд: 1–3 месяца. Стоимость — после анализа требований.







