Розробка серверної частини (Backend) для мобільного додатку на Python (Django/FastAPI)
Уявіть: ваш мобільний додаток виріс до 100 000 DAU, а сервер перестає справлятися з піковими навантаженнями. MongoDB кластеризація вже не допомагає — потрібен відмовостійкий бекенд на Python з грамотною архітектурою. Python — друга за популярністю мова для мобільних бекендів після Node.js, і у нас є дві домінуючі опції: Django REST Framework — batteries-included, ORM, admin, auth з коробки; FastAPI — асинхронний, типобезпечний, швидкий старт. Вибір між ними залежить від вимог до швидкості розробки, продуктивності та розміру команди. Наші інженери з досвідом 10+ років допоможуть визначитися та реалізують проект під ключ за 2–3 тижні (MVP) або 1–3 місяці (повноцінний бекенд). Зв'яжіться з нами, щоб обговорити деталі.
Як вибрати між Django REST Framework та FastAPI?
Ключова відмінність — модель виконання та вбудовані можливості. FastAPI з першого дня працює асинхронно на asyncio, що дає високу пропускну здатність при роботі з I/O-bound операціями (мережеві запити, робота з БД). Django REST Framework історично синхронний, але з версії 4.1 підтримує асинхронні view через ASGI. Якщо ваш проект вимагає real-time фіч, WebSocket, високої конкурентності — FastAPI очевидний вибір. Якщо ж потрібна швидка розробка з адмін-панеллю та багатим ORM, DRF заощадить тижні.
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, push-сповіщень, важкі обчислення).
# 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 |
Типові помилки при виборі архітектури бекенду
- Ігнорування вимог до real-time: якщо додатку потрібні сповіщення в реальному часі, краще одразу закладати WebSocket та асинхронний фреймворк. Перехід з синхронного Django на async у процесі — затратна міграція.
- Недооцінка мікросервісної архітектури: на старті достатньо моноліту, але якщо планується зростання до 50+ ендпоінтів, варто передбачити розбиття на мікросервіси. Python добре підходить для мікросервісів з використанням FastAPI або Nameko.
- Відсутність автоматичної документації API: мобільні розробники витрачають години на узгодження форматів. OpenAPI (Swagger) вирішує цю проблему.
Як забезпечити безпеку API?
Окрім JWT, ми використовуємо CORS, rate limiting, валідацію вхідних даних, логування підозрілої активності. Для захисту від SQL-ін'єкцій застосовуємо ORM з параметризованими запитами. Всі секрети зберігаються у Vault або AWS Secrets Manager. Регулярно оновлюємо залежності.
Для додаткового захисту впроваджуємо TOTP через pyotp та QR-коди. Це знижує ризики компрометації акаунту на 99% (за даними OWASP).
Розгортання
FastAPI або Django запускається через Uvicorn + Gunicorn з кількома воркерами. Docker з багатоетапною збіркою для мінімального образу. Nginx як reverse proxy. PostgreSQL + Redis у docker-compose для локалу, RDS + ElastiCache для продакшену. З такою конфігурацією ми гарантуємо SLA 99.9% і знижуємо витрати на інфраструктуру до 40% порівняно з монолітним підходом.
Етапи робіт над бекендом
- Аналіз вимог — вивчаємо ТЗ, навантаження, інтеграції. Оцінюємо строки.
- Проектування API — специфікація OpenAPI, вибір стеку.
- Розробка — реалізація модулів, налаштування БД, аутентифікації, фонових задач.
- Тестування — unit-тести, інтеграційні, навантажувальні (locust/k6).
- Деплой — Docker, CI/CD (GitHub Actions), моніторинг (Prometheus + Grafana).
Що входить у розробку
- Проектування API під вимоги мобільного клієнта
- Налаштування PostgreSQL + Alembic міграції
- Auth (JWT)
- CRUD-модулі
- Push-сповіщення (Firebase Admin SDK)
- Фонові задачі (Celery)
- Docker + CI/CD
- Документація OpenAPI
- Консультації на всіх етапах
Строки та вартість
MVP (Auth + 3–5 ресурсів): від 2 до 3 тижнів. Повноцінний бекенд: від 1 до 3 місяців. Вартість розраховується індивідуально після аналізу вимог. Наші інженери з досвідом 50+ проектів гарантують якість та дотримання строків. Замовте розробку бекенду під ключ — отримайте консультацію вже сьогодні.







