Co je Node.js a proč se hodí pro serverové skriptování
Node.js je běhové prostředí pro JavaScript postavené nad enginem V8, které umožňuje spouštět JS mimo prohlížeč. Díky event-driven a non-blocking I/O architektuře se hodí pro síťové aplikace s vysokou paralelní zátěží (API, realtime komunikace, proxy, streamovací brány). Silnou stránkou je jednotný jazyk napříč frontendem i backendem, bohatý ekosystém balíčků a snadná práce se JSONem.
Událostní smyčka, vlákna a model konkurence
Node.js používá event loop v jednom hlavním vlákně pro řízení asynchronních operací (časovače, I/O, síť). Blokující úlohy (např. kryptografie, komprese) provádí v pozadí libuv pomocí thread poolu. Pro CPU-intenzivní práci lze využít worker_threads nebo horizontální škálování přes cluster. Klíčové je navrhovat kód tak, aby neblokoval smyčku (vyhnout se synchronním I/O, dlouhým smyčkám, velkým serializacím na hlavním vlákně).
Moduly: CommonJS vs. ECMAScript Modules
Node.js podporuje CommonJS (require/module.exports) i ESM (import/export). Volba ovlivňuje způsob načítání, cache i interoperabilitu. Doporučený směr je ESM, který je standardem v JS ekosystému. Konfigurace probíhá pomocí type v package.json a/nebo přípon .mjs/.cjs. Při návrhu knihoven dbejte na jasnou distribuci (dual-package, export mapy) a pečlivé určení engines (minimální verze Node.js).
Správa závislostí a monorepa
Balíčky se spravují přes npm, yarn nebo pnpm. Pro větší kódové základny je běžná organizace do monorepa s workspaces a nástroji jako Turborepo či Nx. Důležité je uzamykat přesné verze (package-lock.json/pnpm-lock.yaml), pečovat o audit zranitelností a používat semantic versioning. Při běhu v produkci preferujte --omit=dev (instalace bez dev závislostí) a deterministické buildy.
Serverové frameworky a architektonické styly
- Minimalistické HTTP frameworky: Express, Fastify – rychlý start, middleware, pluginy, validace, serializace.
- Opinionated a modulární: NestJS – dependency injection, moduly, interceptory, filtry, integrace s GraphQL, WebSockety.
- GraphQL servery: Apollo, Yoga – schémata, resolvery, federace, per-request kontext.
- Serverless/edge adaptér: lehké runtime-agnostic knihovny (Hono, Elysia) pro nasazení na edge platformy.
API vrstvy: REST, RPC a GraphQL
REST je srozumitelný a dobře cacheovatelný. RPC (např. tRPC) zjednodušuje typovou bezpečnost mezi klientem a serverem. GraphQL je vhodný pro složité klientské aplikace s potřebou flexibilních dotazů; vyžaduje však důsledný query cost management, dataloadery a per-field autorizaci.
Asynchronní programování: Promise, async/await, streamy
Preferujte async/await pro čitelnost, avšak dbejte na paralelizaci pomocí Promise.all tam, kde to dává smysl. Streamy (Readable/Writable/Transform/Duplex) jsou klíčové pro efektivní práci s velkými daty (upload/download, komprese, parsování). Používejte backpressure a pipeline utilitu pro bezpečné řetězení.
Práce s databázemi a datovou vrstvou
- SQL: knihovny Knex, node-pg, mysql2, a ORMy jako Prisma nebo TypeORM. Důraz na connection pooling, transakce a migrace.
- NoSQL: MongoDB (Mongoose), dokumentové a klíč-hodnota store. Navrhujte sharding/TTL a správné indexy.
- Cache: Redis jako in-memory cache, rate-limit store, pub/sub a distribuované zámky.
- Fronty a streamy: RabbitMQ, Kafka, SQS – pro asynchronní workflow, outbox pattern a exactly-once semantiku (kompenzační transakce).
Autentizace a autorizace
JWT a PASETO jsou běžné pro stateless přístupové tokeny, session s podepsaným cookie je vhodná pro tradiční weby. Dbejte na rotaci klíčů (JWKS), krátkou životnost tokenu, refresh token flow a RBAC/ABAC v aplikační vrstvě. Na API bráně aplikujte rate limiting, IP allow-list, mTLS dle potřeby.
Bezpečnost serveru a závislostí
- HTTP ochrany: hlavičky (HSTS, CSP, X-Frame-Options), CSRF pro stateful weby, sanitace vstupů.
- Secrets management: nepoužívat tajemství v
.envv repozitáři, ale bezpečný trezor; rotace a audit přístupů. - Dependabot/audit: pravidelný audit zranitelností, omezení postinstall skriptů, lockfile integrita.
- SSR/templating: escapování výstupu a prevence XSS, bezpečný template rendering.
Konfigurace, 12-Factor a prostředí
Konfigurace patří do proměnných prostředí. Oddělte build a run fázi, logujte do STDOUT, používejte immutable buildy. Udržujte idempotentní start (bez postranních efektů). Zaveďte feature flags pro řízené nasazování.
Logování, metriky a observabilita
- Strukturované logy (JSON) s korelačními ID pro sledování požadavků napříč službami.
- Metriky: latence, throughput, chybovost, saturace (RED/USE). Export do Promethea/StatsD.
- Traces: OpenTelemetry SDK pro distribuované trasování (span context přes HTTP/AMQP).
Výkon a škálování
- Horizontální škálování více procesů (cluster) za reverzní proxy (NGINX/Envoy) s sticky sessions dle potřeby.
- Worker Threads pro CPU těžké operace (hashování, PDF, obrázky), vyhněte se blokujícímu kódu.
- Optimalizace V8: vyvarujte se polymorfismu horkých funkcí, stabilní shape objektů, recyklace alokací.
- Streamy a backpressure pro velké přenosy, zero-copy metody (
fs.createReadStream→res).
Testování a kvalita
- Jednotkové a integrační testy (Jest, Vitest, Mocha) s izolací závislostí a fixtures.
- Contract testy pro rozhraní mezi mikroslužbami (Pact).
- e2e testy API (Supertest), případně pro SSR/SPA části prohlížečové testy (Playwright).
- Static analysis a TypeScript pro typovou bezpečnost, ESLint a Prettier pro konzistenci.
Typy běhu: dlouho běžící služby, cron a serverless
Node.js umí spolehlivě běžet jako dlouhotrvající proces (HTTP servery, WebSocket huby), ale je také vhodný pro cron a dávky (např. s knihovnami pro plánování). V prostředí serverless je nutná inicializace bez stavů, rychlý cold start, krátké připojení k DB (pooling přes proxy) a idempotence handlerů.
Nasazení: kontejnery, orchestrátory a procesní manažery
- Kontejnerizace: malé immutable image (alpine/distroless), multi-stage build, non-root uživatel, healthcheck.
- Orchestrace: Kubernetes (readiness/liveness, HPA podle CPU/RAM/latence), service mesh (mTLS, retries, circuit breaking).
- Procesní manažer: PM2 nebo systemd pro restart po pádu, rolling restarty a log rotaci v tradičních VM.
HTTP, WebSocket a realtime
Pro realtime notifikace použijte WebSockety nebo SSE. Důležité je škálovat pub/sub vrstvu (Redis, NATS) a řešit presence, backoff a resubscribe po výpadku. Rate-limitujte události a mějte kvóty per-tenant.
Souborový systém, uploady a CDN
Velké uploady obsluhujte přes multipart streaming a ukládejte do objektových úložišť s podpisovanými URL (pre-signed). Stahování servírujte přes CDN, server v Node.js pouze generuje odkazy a kontroluje přístupová práva.
Mezijazyková interoperabilita a nativní doplňky
Pro integraci s nativním kódem slouží N-API a node-addon-api. Vyžaduje to pečlivé verzování a CI pro různé platformy. Alternativou jsou externí mikroslužby v jiném jazyce komunikující přes HTTP/gRPC, což zjednodušuje build, ale přidává síťovou latenci.
Stabilita, odolnost a vzory spolehlivosti
- Circuit breaker, bulkhead, retry s jitterem a timeouty na všech výstupech.
- Graceful shutdown: zachycení signálů, dokončení rozpracovaných požadavků, uzavření poolů.
- Idempotence: opakovatelné operace v dávkách a webhooky chráněné podpisy a replay-detekcí.
Mezinárodní prostředí, lokalizace a formátování
Využívejte Intl API pro formátování čísel, měn a časů, vyvarujte se manuálního parsingu. Čas vždy ukládejte jako UTC, uživateli prezentujte v jeho časové zóně. Pro lokalizaci zpráv používejte ICU message formát a externí slovníky.
Správa verzí Node.js a LTS strategie
Nasazujte na LTS řadách, sjednoťte verzi pomocí .nvmrc nebo engines v package.json. Při CI implementujte matrix buildy pro cílové verze a pravidelně testujte kompatibilitu. Sledujte deprecace a změny v API (fs/promises, URL, WHATWG Streams).
Observabilita výkonu a profilování
- CPU profil a heap snapshot pro hledání úniků paměti, flamegraphy pro „hot paths“.
- Event loop lag monitorujte a snižujte přes delegaci CPU práce do workerů.
- GC tuning – šetřete alokacemi, používejte pooling bufferů, pozor na neúmyslné retenční reference.
Mikroslužby a kontrakty
Node.js je vhodné pro lehké mikroslužby: každá má jasný bounded context, smluvené kontrakty (OpenAPI/AsyncAPI), backward-compatible změny a verzování endpointů. Dodržujte consumer-driven contracts a CI validace schémat.
Bezstavové vs. stavové služby
Preferujte bezstavovost a stav ukládejte do externích systémů (DB, cache, fronty). Pokud je stav nevyhnutelný (např. herní realtime), použijte sticky sessions, robustní replikaci a conflict resolution. Plánujte rebalance při škálování.
Praktické zásady pro produkci
- Vždy nastavte time-outy na HTTP klienty i servery a limity velikosti požadavků.
- Logujte korelační ID a uživatele/tenant (bez PII) pro dohledatelnost.
- Automatizujte CI/CD (lint, testy, build, scan, release, canary deploy, rollback).
- Vytvářejte chaos scénáře (síťová latence, výpadky závislostí) a testujte odolnost.
Typické antipatterny a jak se jim vyhnout
- Blokující synchronní kód v cestě požadavku (soubory, CPU smyčky).
- Neřízené promisy (zapomenuté await, nezachycené odmítnutí), chybějící try/catch.
- „God server“ bez modulárního návrhu, míchání transportní a doménové logiky.
- Nevalidované vstupy a serializace bez schémat (JSON schema/Zod) – vede k exploatovatelným chybám.
Závěr
Node.js je vyzrálé a výkonné prostředí pro serverové skriptování. Vyniká tam, kde je klíčová asynchronní I/O práce, rychlý vývoj a sdílený jazyk napříč stackem. Úspěšná produkce stojí na správném asynchronním návrhu, kvalitní observabilitě, bezpečnosti, typové disciplíně a promyšleném nasazení. Dodržením uvedených zásad získáte škálovatelnou, spolehlivou a ekonomicky efektivní platformu pro moderní backendové služby.
