To nie są dodatki „na później”, jeśli projekt ma działać poza lokalnym środowiskiem. Cache potrafi zdjąć ogromną część ruchu z bazy, ale może też zwracać nieaktualne dane. Kolejka ratuje przy wolnych operacjach, ale wymaga idempotencji. Deployment bez monitoringu daje tylko wiarę, że wszystko działa.
1. Cache — przyspieszanie odpowiedzi
Cache nie jest tylko optymalizacją na koniec projektu. To sposób na zdjęcie pracy z bazy, API zewnętrznych i serwera, ale też źródło trudnych błędów, jeśli nie wiesz, kiedy dane stają się nieaktualne.
Redis
Redis to in-memory database często używana jako cache, magazyn sesji, kolejka albo mechanizm pub/sub. Warto też znać Valkey, czyli forka Redis wspieranego przez Linux Foundation po zmianach licencyjnych w ekosystemie Redis. W najprostszym wariancie trzymasz w nim wynik wolnego zapytania przez kilka minut:
W praktyce równie ważna jak samo zapisanie jest strategia unieważniania cache po zmianie danych.
Kiedy cachować?
Cache ma sens tam, gdzie odczyt jest częsty, a zmiana rzadsza albo akceptujesz chwilowo nieświeże dane. Nie cachuj wszystkiego automatycznie, bo każdy cache trzeba potem unieważnić.
- Dane często czytane, rzadko zmieniane
- Wolne zapytania do bazy
- Wywołania zewnętrznych API
- Obliczenia / agregacje
Strategie cache
Cache-aside () — najczęstsze:
Write-through — zapis idzie najpierw do cache, potem do bazy. Cache zawsze świeży.
Write-behind — zapis do cache od razu, do bazy asynchronicznie. Najszybsze, ale ryzyko utraty danych.
Stale-while-revalidate — zwróć stary cache od razu, w tle odśwież.
Unieważnianie cache — najtrudniejsza rzecz w programowaniu
"There are only two hard things in Computer Science: cache invalidation and naming things." — Phil Karlton
Problem polega na tym, że cache przyspiesza odczyt, ale oddala Cię od źródła prawdy. Masz trzy podstawowe podejścia:
- TTL (
expire after N) — proste, przewidywalne, ale dane mogą być nieaktualne przez chwilę. - Event-driven — po
UPDATEw bazie wyczyść konkretne klucze (del('user:123')). - Versioning — klucz zawiera wersję (
user:123:v5); zmieniasz wersję, stare wpisy zostają, ale nikt ich nie czyta.
Nie używaj KEYS users:list:* na produkcji — może zablokować Redis przy dużej liczbie kluczy. Jeśli musisz usuwać po wzorcu, użyj SCAN partiami albo trzymaj własny indeks kluczy per tag, jak w przykładzie wyżej.
Cache stampede — gdy wszyscy naraz przebijają cache
Cache może też zaszkodzić, gdy popularny klucz wygasa i nagle setki requestów jednocześnie idą do bazy. To cache stampede. Typowe zabezpieczenia:
- jitter w TTL — dodaj losowe kilka-kilkadziesiąt sekund, żeby klucze nie wygasały naraz,
- lock per klucz — tylko jeden request odbudowuje cache, reszta czeka albo dostaje stary wynik,
- stale-while-revalidate — użytkownik dostaje starszą odpowiedź, a backend odświeża cache w tle,
- pre-warming — najważniejsze klucze odświeżasz zanim wygasną.
HTTP cache — drugi (i pierwszy) poziom
Backend Redis to nie wszystko — przeglądarka i cache'ują na bazie nagłówków HTTP. Frontendowiec widzi to w Network tabie jako (disk cache) / (memory cache) / from CDN.
| Header | Co robi |
|---|---|
Cache-Control: public | CDN może cachować |
Cache-Control: private | Tylko przeglądarka użytkownika |
Cache-Control: no-store | Nie cachuj wcale |
Cache-Control: no-cache | Cachuj, ale zawsze rewaliduj |
max-age=3600 | Cache świeży przez godzinę |
s-maxage=3600 | TTL tylko dla CDN (override max-age) |
stale-while-revalidate=N | Po expiry serwuj stary, w tle pobierz świeży |
stale-if-error=N | Po błędzie serwuj stary (graceful degradation) |
ETag: "abc" | Hash zawartości — przeglądarka pyta "czy jest nowsze?" |
Conditional request:
Trzy poziomy cache
Dobra aplikacja cachuje na każdym poziomie, gdzie ma to sens.
Next.js / framework caches
Nowoczesne frameworki mają własne warstwy:
- Next.js Data Cache — cachuje wyniki
fetch()zrevalidate - Next.js Full Route Cache — całe HTML strony statycznej
- React
cache()— deduplikacja w obrębie jednego renderu use cache— aktualny model cache w Next.js 16 przy włączonych Cache Componentsunstable_cache— starsze API z tagami i rewalidacją, nadal spotykane w projektach sprzed migracji
W Next.js 16 unstable_cache zostało zastąpione przez dyrektywę use cache. Ważna zasada pozostaje taka sama: nie czytaj cookies() ani headers() bezpośrednio we współdzielonym zakresie cache. Dane zależne od użytkownika przekaż jako argument albo użyj mechanizmu przeznaczonego do prywatnego cache.
2. Kolejki i zadania w tle
Nie każdy proces powinien kończyć się w czasie jednego requestu. Wysyłka maila, przeliczenie raportu, generowanie PDF-a, synchronizacja CRM czy przetwarzanie płatności mogą trwać za długo albo zależeć od zewnętrznego systemu. Kolejka pozwala szybko odpowiedzieć użytkownikowi, a ciężką pracę wykonać w tle.
Popularne: BullMQ (Redis), RabbitMQ, AWS SQS, Inngest, Trigger.dev (event-driven, type-safe).
Idempotencja i deduplikacja zadań
Kolejka nie daje automatycznie gwarancji „dokładnie raz”. W praktyce wiele systemów działa w modelu at-least-once, czyli job może zostać wykonany więcej niż raz: po retry, restarcie workera albo chwilowej awarii. Dlatego zadania muszą być idempotentne.
Po stronie workera nadal warto zapisać efekt w bazie:
Reguła: retry ma naprawiać błędy przejściowe, a nie tworzyć duplikaty.
Cron / zadania cykliczne
Cron to praca cykliczna: raport nocny, czyszczenie cache, naliczenie subskrypcji, przypomnienia mailowe. Prosty mechanizm, ale w produkcji musi być idempotentny i monitorowany, bo dwa równoległe uruchomienia potrafią narobić szkód.
Reguły dla cron:
- Idempotency — zadanie może odpalić się dwa razy (deploy, retry)
- Lock — przy wielu instancjach tylko jedna ma wykonać (Redis lock, advisory lock w Postgres)
- Monitoring — alert jeśli zadanie się nie wykonało (Healthchecks.io, Better Stack)
W produkcji użyj zarządzanej platformy: Vercel Cron, Cloudflare Cron Triggers, Inngest, GitHub Actions (cron + curl), Kubernetes CronJob.
Wzorce przetwarzania
- Fan-out — jedno zdarzenie → wiele jobów (np. nowy użytkownik → wyślij e-mail + utwórz workspace + zapisz w CRM)
- Pipeline — job A → job B → job C
- Retry with backoff — przy błędzie spróbuj ponownie z opóźnieniem (1s, 2s, 4s, 8s...)
- Dead letter queue — joby, które padły N razy, lądują na DLQ do manualnej analizy
Do tego dodaj alert: jeśli dead letter queue rośnie, system może dalej odpowiadać 200, ale biznesowo przestaje wykonywać pracę.
3. File storage
Pliki mają inne wymagania niż rekordy w bazie. Obrazy, dokumenty, avatary i eksportowane PDF-y zwykle nie powinny trafiać bezpośrednio do relacyjnej bazy danych. Najczęściej zapisujesz je w object storage, a w bazie trzymasz tylko metadane i ścieżkę.
Popularne: AWS S3, Cloudflare R2 (zero egress fee!), Google Cloud Storage, Backblaze B2, MinIO (hostowane samodzielnie).
Presigned URLs — upload bezpośrednio z frontu
W większych systemach backend nie powinien przepuszczać każdego pliku przez siebie. Zamiast tego generuje presigned URL, a frontend uploaduje plik bezpośrednio do storage. Backend kontroluje uprawnienia i zapisuje metadane, ale nie musi trzymać całego pliku w pamięci.
Plusy:
- Backend nie przepuszcza pliku przez siebie — oszczędza pamięć i transfer
- Skalowalne — S3 wytrzyma więcej niż Twój serwer
- Szybsze dla użytkownika — brak przejścia przez backend
Bezpieczeństwo uploadu
Presigned URL nie znaczy „dowolny upload”. Backend nadal musi narzucić zasady:
- allowlista MIME — np. tylko
image/jpeg,image/png,image/webp,application/pdf, - limit rozmiaru — najlepiej egzekwowany polityką uploadu albo po stronie storage,
- bezpieczny klucz — nie ufaj nazwie pliku od użytkownika; generuj własny prefiks i UUID,
- prywatny bucket domyślnie — publiczny dostęp dawaj tylko tam, gdzie naprawdę jest potrzebny,
- walidacja po uploadzie — sprawdź metadata, rozmiar i typ zanim zapiszesz plik jako aktywny,
- skanowanie plików — szczególnie przy PDF-ach, dokumentach i uploadach dostępnych dla innych użytkowników,
- osobny etap publikacji — upload może trafić do katalogu tymczasowego, a dopiero worker przenosi go do docelowej lokalizacji.
CDN dla statycznych plików
Pliki publiczne (avatary, obrazki postów) idą zwykle przez CDN — Cloudflare, Bunny, CloudFront:
Optymalizacja obrazów
Surowe obrazy są ciężkie. Najpopularniejsze podejścia:
- Next.js Image — automatyczne resize, WebP / AVIF, lazy loading
- Cloudinary / imgix / Cloudflare Images — managed image CDN z transformacjami w URL
- Sharp (Node) — backend-side resize / optimize przy upload
4. Środowiska i deployment
Kod działający lokalnie to dopiero początek. Backend musi mieć środowiska, sekrety, migracje, monitoring, backupy i powtarzalny deployment. Bez tego każda zmiana na produkcji zaczyna przypominać ręczną operację na żywym organizmie.
Środowiska
Zmienne środowiskowe
Nigdy nie commituj .env do repo!
Opcje deploymentu
Nie ma jednego najlepszego hostingu dla backendu. Wybór zależy od tego, czy chcesz prostoty, kontroli, globalnego edge, czy przewidywalnych kosztów.
Platform as a Service (łatwe):
- Vercel (Next.js)
- Railway
- Render
- Heroku
Container (więcej kontroli):
- Docker + Kubernetes
- AWS ECS
- Google Cloud Run
VPS (pełna kontrola):
- DigitalOcean
- AWS EC2
- Hetzner (Niemcy, świetna cena/wydajność)
- Coolify (PaaS hostowany samodzielnie na własnym VPS)
Edge / :
- Cloudflare Workers
- Vercel Edge Functions
- Deno Deploy
- AWS Lambda + API Gateway
- Fly.io (globalne VM)
CI/CD — automatyzacja deploymentu
Deploy nie powinien zależeć od tego, kto ma akurat poprawnie skonfigurowany laptop. Pipeline w GitHub Actions albo GitLab CI sprawia, że testy, build i wdrożenie są powtarzalne:
Minimum sensownego pipeline'u:
- Instalacja zależności z lockfile (
npm ci,pnpm install --frozen-lockfile). - Lint, testy jednostkowe i testy typów.
- Build produkcyjny.
- Skan sekretów i zależności.
- Migracje bazy w kontrolowanym kroku.
- Deploy.
- Smoke test po wdrożeniu.
Strategie deploymentu
- Blue-green — dwa środowiska, switch ruchu w jednej chwili (zero downtime)
- Canary — nowa wersja dostaje 1% ruchu, jeśli nie pada → 10% → 50% → 100%
- Rolling — instancje aktualizowane po kolei (Kubernetes default)
- Feature flags — kod wdrożony, ale wyłączony; włączany per użytkownik albo kohorta (LaunchDarkly, Unleash, GrowthBook)
Migracje bazy bez downtime
Najczęstszy błąd przy deploymentach backendu to założenie, że kod i baza zmienią się dokładnie w tej samej sekundzie. W realnym wdrożeniu przez chwilę mogą działać dwie wersje kodu: stara i nowa. Migracje muszą być z nimi kompatybilne.
Bezpieczny wzorzec to expand → migrate → contract:
- Expand — dodaj nową kolumnę/tabelę jako opcjonalną, bez usuwania starego pola.
- Deploy kodu — nowa wersja potrafi pisać do starego i nowego modelu albo czytać oba.
- Backfill — uzupełnij dane w tle, partiami.
- Przełącz odczyt — aplikacja zaczyna czytać z nowej struktury.
- Contract — dopiero po czasie usuń stare pole.
Unikaj migracji, które długo blokują tabele w godzinach ruchu. Przy dużych tabelach indeksy, backfill i zmiany NOT NULL trzeba planować osobno.
Health checks, readiness i rollback
Backend powinien mieć przynajmniej dwa endpointy kontrolne:
Po wdrożeniu uruchom smoke test: zalogowanie testowego użytkownika, podstawowy endpoint API, zapis/odczyt z bazy i jeden krytyczny flow biznesowy. Rollback też musi być przećwiczony: jeśli nowy kod jest cofany, baza nadal musi być kompatybilna z poprzednią wersją aplikacji.
Backups i disaster recovery
Backup jest użyteczny dopiero wtedy, gdy potrafisz go odtworzyć. Sama informacja „mamy backupy” niewiele znaczy, jeśli nikt nigdy nie sprawdził restore'u.
- Automatyczne backupy bazy (PostgreSQL:
pg_dump, point-in-time recovery) - Test restore — backup, którego nie odtworzyłeś, nie istnieje
- RTO (Recovery Time Objective) — jak długo system może być niedostępny
- RPO (Recovery Point Objective) — ile danych możesz stracić
5. Monitoring i logging
Bez monitoringu backend jest czarną skrzynką. Widzisz tylko, że użytkownik zgłasza problem, ale nie wiesz, czy zawiodła baza, zewnętrzne API, deployment, cache czy konkretna ścieżka w kodzie.
Logi
Narzędzia: Winston, Pino, Datadog, Papertrail
Monitoring
Monitoring odpowiada na pytanie, czy system działa zdrowo. Logi mówią, co się wydarzyło w konkretnym przypadku, a metryki pokazują trend i skalę problemu.
- Uptime — czy serwer działa?
- Latency — jak szybko odpowiada?
- Errors — ile błędów 5xx?
- Resources — CPU, RAM, disk
Narzędzia: Grafana, Datadog, New Relic, Sentry (errors), Better Stack, Honeycomb.
Trzy filary observability
- Logs — co się stało (event-by-event)
- Metrics — ile czego (latency, throughput, errors)
- Traces — pełna ścieżka requestu przez system (request-id przez wszystkie usługi)
Minimum praktyczne dla frontendowca i backendowca to wspólny request ID. Backend zwraca go w nagłówku, frontend dołącza do raportu błędu, a logi pozwalają znaleźć dokładny request.
Distributed tracing
W większych systemach pojedynczy request często przechodzi przez kilka usług. Bez trace'u widzisz tylko „endpoint trwa 800 ms”. Z trace'em widzisz, że 600 ms zjada konkretne zapytanie do bazy albo jedna integracja zewnętrzna.
Standard: OpenTelemetry (otel) — agnostic; eksportuje do Datadog, Honeycomb, Tempo, Jaeger.
Alerty — co budzi w nocy
Alert powinien odpowiadać na objaw, nie na przyczynę. SRE Google wyznacza tzw. "Four Golden Signals":
- Latency — p50 / p95 / p99 czasu odpowiedzi
- Traffic — RPS (requests per second)
- Errors — % błędów 5xx
- Saturation — wykorzystanie CPU, RAM, disku, pool connections
Alert niech budzi tylko wtedy, gdy użytkownik faktycznie odczuwa problem. Reszta to ticket „do obejrzenia”.
Frontend → backend observability
Frontend też powinien wysyłać błędy i metryki. Sentry, LogRocket, Datadog RUM pokazują, jak użytkownik dochodzi do błędu. Powiąż user-id / request-id między frontem a backendem, żeby widzieć całą ścieżkę.
6. Bezpieczeństwo
Bezpieczeństwo backendu nie polega na jednej bibliotece ani checkliście odhaczonej przed wdrożeniem. To zestaw nawyków: walidujesz dane, ograniczasz uprawnienia, nie ufasz klientowi, logujesz zdarzenia i zakładasz, że każdy publiczny endpoint będzie testowany przez kogoś nieżyczliwego.
Podstawowe zasady
- Waliduj input — nigdy nie ufaj danym od użytkownika
- Parametryzuj zapytania — unikaj injection
- Hashuj hasła — bcrypt, argon2
- HTTPS everywhere — szyfruj transmisję
- Rate limiting — ogranicz requesty
- Autoryzuj na backendzie — może ukryć przycisk, ale nie może być źródłem prawdy
- CORS — kontroluj, które originy mogą czytać odpowiedzi z API
Rate limiting w praktyce
Frontend reaguje na 429:
W produkcji rate limiting zwykle siedzi na CDN / WAF (Cloudflare, AWS WAF), nie w aplikacji — chroni przed DDoS i nie zużywa zasobów backendu.
CORS to nie autoryzacja
CORS mówi przeglądarce, czy JavaScript z danego origina może odczytać odpowiedź. Nie blokuje curl, aplikacji mobilnej, backendu ani atakującego, który woła API bezpośrednio. Dlatego CORS jest warstwą kontroli przeglądarki, a nie mechanizmem uprawnień.
Backend nadal musi sprawdzić sesję, token, role i właściciela zasobu.
OWASP Top 10:2025 — must-know
OWASP Top 10 to lista najważniejszych kategorii ryzyk aplikacji webowych. Aktualną wersją jest OWASP Top 10:2025. Nie musisz znać każdego scenariusza ataku na pamięć, ale jako frontendowiec powinieneś rozumieć, które problemy są rozwiązywane wyłącznie po stronie backendu.
- Broken Access Control — sprawdzanie uprawnień na backendzie, nie tylko ukrywanie przycisków w UI.
- Security Misconfiguration — debug w produkcji, otwarte buckety, domyślne hasła, złe nagłówki.
- Software Supply Chain Failures — zależności, build pipeline, lockfile, paczki npm, obrazy Dockera.
- Cryptographic Failures — HTTPS wszędzie, bezpieczne algorytmy, brak danych wrażliwych w logach.
- Injection — SQL injection, XSS, NoSQL injection, command injection.
- Insecure Design — np. brak rate limitu na reset hasła albo brak modelu uprawnień.
- Authentication Failures — słabe hasła, brak MFA, długie sesje, zły reset hasła.
- Software or Data Integrity Failures — niepodpisane artefakty, niekontrolowane aktualizacje, zaufanie do niezweryfikowanych danych.
- Security Logging and Alerting Failures — nie wiesz, że trwa atak albo wyciek.
- Mishandling of Exceptional Conditions — wyjątki ujawniają dane, pomijają autoryzację albo zostawiają system w złym stanie.
SSRF nie zniknął jako problem — w OWASP Top 10:2025 został włączony w szerszą kategorię Broken Access Control.
XSS — Cross-Site Scripting
Atakujący wstrzykuje JS w kontekst Twojej domeny (komentarz, profil). Skradzione cookies, wyświetlone fałszywe formularze.
Obrona:
- Escapuj output — React i większość frameworków robi to domyślnie. Uważaj na
dangerouslySetInnerHTML. - Content-Security-Policy (CSP) — header, który mówi przeglądarce, skąd wolno ładować skrypty:
Code
- Sanityzuj HTML od użytkownika — DOMPurify, sanitize-html
Walidacja input — nigdy nie ufaj klientowi
Walidacja w formularzu poprawia UX. Walidacja na serwerze chroni system. Użytkownik może wyłączyć JavaScript, zmodyfikować payload w DevTools albo wysłać request z własnego skryptu.
Reguła: klient waliduje dla UX, serwer waliduje dla bezpieczeństwa.
Mass assignment
Secret management
Sekrety nigdy nie idą do repo, nawet do prywatnego.
- Lokalnie:
.env+.gitignore,direnv, 1Password CLI - CI/CD: GitHub Secrets, GitLab CI Variables
- Produkcja: AWS Secrets Manager, HashiCorp Vault, Doppler, Infisical
- Rotacja — sekrety powinny mieć datę ważności (klucze API, hasła do bazy)
Jeśli sekret kiedyś trafił do repo (nawet usuniętego commita) — uznaj go za skompromitowany i wymień. Git history żyje wiecznie.
Supply chain i zależności
Bezpieczeństwo zależy też od tego, co instalujesz i jak budujesz aplikację:
- commituj lockfile i instaluj zależności komendą deterministyczną (
npm ci,pnpm --frozen-lockfile), - włącz Dependabot albo Renovate,
- używaj
npm auditz rozsądkiem: nie każda podatność dotyczy ścieżki produkcyjnej, ale krytycznych nie ignoruj, - pinuj obrazy Dockera do wersji albo digestu,
- skanuj sekrety w CI,
- ogranicz uprawnienia tokenów CI/CD do minimum,
- nie uruchamiaj skryptów z internetu bez sprawdzenia, co robią.
SSRF — szczególnie przy URL-ach od użytkownika
SSRF pojawia się, gdy backend pobiera URL podany przez użytkownika: import obrazka, webhook testowy, parser Open Graph, PDF generator. Atakujący może próbować zmusić serwer do połączenia z adresem wewnętrznym, np. metadata service w chmurze.
Obrona:
- allowlista hostów albo domen,
- blokada prywatnych adresów IP (
127.0.0.1,10.0.0.0/8,169.254.169.254, IPv6 local), - limit rozmiaru odpowiedzi i timeout,
- brak przekazywania sekretów do pobieranego URL,
- osobny worker/sandbox do pobierania nieufnych zasobów.
Security headers
Standardowe headery, które dodaje helmet:
Zwraca między innymi:
Strict-Transport-Security— wymuszaj HTTPS przez N dni (HSTS)X-Content-Type-Options: nosniff— przeglądarka nie zgaduje MIMEX-Frame-Options: DENY— chroni przed clickjackingReferrer-Policy: strict-origin-when-cross-originPermissions-Policy— wyłącza geolokalizację, kamerę itd. domyślnie
Sprawdź swoje headery na securityheaders.com.
GDPR / RODO — minimalne minimum
Jeśli zbierasz dane od użytkowników z UE:
- Cel przetwarzania — wiedz, po co masz dane
- Right to access / erasure — endpoint pozwalający exportować i kasować dane
- Pseudonimizacja — adres IP w logach maskuj
- Consent — banner cookie dla narzędzi analitycznych
- DPA — umowa powierzenia z każdym dostawcą przetwarzającym dane
Co dalej? — ścieżka nauki
Nie próbuj uczyć się backendu przez czytanie wszystkiego naraz. Najszybciej rośnie się przez mały projekt, który dotyka kilku prawdziwych problemów: logowania, bazy, walidacji, uploadu, webhooka i deploymentu. Poniższa ścieżka układa tematy od fundamentów do architektury.
Poziom 1: Fundamenty
- HTTP — request / response, kody statusu, nagłówki
- Node.js + Express (lub Hono / Fastify)
- SQL podstawy — CRUD, JOIN, indeksy, transakcje
- design — zasoby, metody, statusy HTTP
- CORS — co to, kiedy psuje requesty, jak konfigurować
Poziom 2: Praktyka
- PostgreSQL + Prisma / Drizzle
- Autentykacja — sesje vs JWT, cookies, CSRF
- Walidacja inputu (Zod) i strukturalne błędy (RFC 9457)
- Deployment — Vercel / Railway / Render
- Webhooks — przyjmowanie i wysyłanie
Poziom 3: Zaawansowane
- Redis / Valkey — strategie cache, pub/sub, kolejki (BullMQ)
- Real-time — i WebSockets
- Docker + pipeline CI/CD
- Monitoring / logging / tracing (OpenTelemetry, Sentry)
- Connection pooling / serverless drivery (PgBouncer, Neon)
Poziom 4: Architektura
- Microservices vs monolith
- Event-driven architecture, kolejki
- CQRS, Event Sourcing
- Distributed systems — CAP theorem, eventual consistency
- Testy obciążeniowe (k6, Artillery)
Projekt do nauki
Najlepszy projekt do nauki nie musi być oryginalny. Ma zmusić Cię do przejścia przez typowe decyzje backendowe. Dobrym kandydatem jest prosty blog z autentykacją:
- Rejestracja / logowanie (sesja albo JWT)
- postów z paginacją
- Komentarze (real-time z SSE — bonus)
- Upload obrazów (presigned URLs do S3 / R2)
- Webhook handler (Stripe sandbox jako „płatne posty”)
- Deployment + CI/CD
- Sentry / monitoring
Taki projekt nie wygląda efektownie na pierwszy rzut oka, ale pokrywa większość problemów, które wracają w komercyjnych aplikacjach: stan użytkownika, dane, uprawnienia, pliki, integracje, błędy i deployment.
| Komponent | Rola | Popularne (2026) |
|---|---|---|
| Serwer | Logika aplikacji | Express, Fastify, Hono, NestJS |
| Runtime | Wykonanie kodu | Node.js, Bun, Deno, Cloudflare Workers |
| Baza danych | Przechowywanie | PostgreSQL, MySQL, MongoDB, SQLite (Turso) |
| ORM / query builder | Abstrakcja bazy | Prisma, Drizzle, Kysely |
| Cache | Przyspieszanie | Redis, Valkey, Memcached, HTTP cache |
| Auth | Bezpieczeństwo | Auth.js, Clerk, Supabase Auth, Better Auth |
| API style | Komunikacja | REST, GraphQL, tRPC |
| Real-time | Push z serwera | SSE, WebSockets, Pusher |
| Storage | Pliki | S3, Cloudflare R2, object storage + CDN |
| Kolejki | Zadania w tle | BullMQ, Inngest, Trigger.dev, SQS |
| Walidacja | Bezpieczny input | Zod, Valibot, Yup |
| Deployment | Hosting | Vercel, Railway, Fly.io, Render, Cloudflare |
| Observability | Co się dzieje | Sentry, Datadog, Better Stack, Honeycomb |
Wybierasz warstwę danych? Porównaj Drizzle ORM i Prisma przed wdrożeniem aplikacji.
