Proč stavět REST API v Node.js a Express.js
Node.js nabízí jednovláknový, event-driven běhový model s vysokou propustností I/O, což z něj činí ideální volbu pro síťové služby. Express.js je minimalistický framework, který přidává směrování, middleware architekturu a ekosystém rozšíření. Tato kombinace je vhodná pro RESTful API díky své jednoduchosti, výkonu a široké komunitě.
Zásady REST: zdroje, reprezentace, uniformní rozhraní
- Zdroj: doménový objekt (např.
/users,/orders), identifikovaný URI. - Reprezentace: typicky JSON s hlavičkou
Content-Type: application/json. - Metody:
GET(čtení),POST(vytvoření),PUT/PATCH(aktualizace),DELETE(mazání). - Bezstavovost: každý požadavek nese veškerý nutný kontext (autentizace, parametry).
- Hypermedia a odkazy (volitelné): například pole
_linkss navigačními odkazy. - Cacheovatelnost: hlavičky
ETag,Cache-Control,Last-Modified.
Struktura projektu: modularita a vrstvy
src/app.js: konfigurace Expressu, middleware, připojení rout.src/routes/*.js: definice cest, mapování na kontrolery.src/controllers/*.js: orchestraci požadavků, validace, odpovědi.src/services/*.js: aplikační logika, doménová pravidla.src/repositories/*.js: přístup k datům (databáze/externí API).src/middlewares/*.js: autentizace, omezení frekvence, logování.src/schemas/*.js: validační schémata (Joi/Zod).src/config: proměnné prostředí, konfigurace.tests/: integrační a jednotkové testy.
Inicializace a závislosti
- Inicializace:
npm init -y - Základní balíčky:
npm i express dotenv - Bezpečnost a utilitky:
npm i helmet cors morgan express-rate-limit - Validace:
npm i zodnebonpm i joi - Testování:
npm i -D jest supertest - Databáze (příklady): MongoDB
npm i mongoose, PostgreSQL s ORMnpm i @prisma/client(+npm i -D prisma)
Spuštění Expressu a základní middleware
V souboru src/app.js nastavte jádro aplikace: JSON parsování, CORS, bezpečnostní hlavičky, omezení frekvence a logování.
app.use(express.json({ limit: "1mb" }))– bezpečné parsování těla požadavku.app.use(cors())– řízení povolených původů; ve výrobním prostředí omezení na specifické domény.app.use(helmet())– zabezpečující hlavičky (proti XSS, clickjackingu apod.).app.use(morgan("combined"))– HTTP logování.rateLimit({ windowMs: 60_000, max: 100 })– omezení zneužití API.
Routing a kontrolery: čisté oddělení
Route definuje strukturu API; kontroler zpracovává validaci, volá službu a vrací odpověď.
- Příklad cesty:
router.get("/users", userController.list) - Kontroler načte
req.query(filtry, stránkování), zavoláuserService.findAlla vrátí odpověď200s JSON. - Pro vytvoření záznamu:
router.post("/users", validate(userSchema), userController.create)
Validace vstupů a sanitace
Validujte vstupní query, params i body. Udržujte validační schémata v blízkosti doménových entit. Příklad se Zod:
const createUserSchema = z.object({ email: z.string().email(), name: z.string().min(2) })function validate(schema) { return (req, res, next) => { const p = schema.safeParse(req.body); if (!p.success) return res.status(400).json({ errors: p.error.issues }); next(); } }
Chybové stavy a jednotný error handler
- Vlastní chyby:
class AppError extends Error { constructor(message, status=400, code="BAD_REQUEST"){ super(message); this.status=status; this.code=code; } } - Globální handler:
app.use((err, req, res, next) => { const status = err.status || 500; res.status(status).json({ error: err.code || "INTERNAL", message: err.message }); }) - Nezachycené chyby/promisy: připojte posluchače
process.on("unhandledRejection")aprocess.on("uncaughtException").
Asynchronní řetězení: async/await a middleware
Zabalte asynchronní kontrolery do helperu, aby nedošlo k nezachyceným chybám: const asyncH = fn => (req,res,next) => Promise.resolve(fn(req,res,next)).catch(next). Používejte u všech kontrolerů.
Persistenční vrstva: Mongoose vs. Prisma
- Mongoose (MongoDB): flexibilní modelování dokumentů; rychlý vývoj, schémata s validací na úrovni modelu.
- Prisma (SQL): typová bezpečnost, migrace, složité dotazy; vhodné pro Postgres/MySQL/SQLite.
- Repository pattern:
userRepository.findById(id)kapsuluje detaily databáze a usnadňuje testování.
Filtrování, stránkování a řazení
- Parametry:
?page=1&limit=20&sort=-createdAt&filter[name]=john - Výstup: metadata
total,page,limit,hasNexta poleitems. - Indexy: navrhujte podle nejčastějších dotazů; u MongoDB využijte
compoundindexy, u SQLbtree/GINpodle typu dat.
Konvence HTTP kódů a odpovědí
200 OKpro čtení,201 Createds hlavičkouLocationpro vytvoření zdroje.204 No Contentpro úspěšnéDELETE.400/422pro chyby validace,401neautentizovaný,403bez oprávnění,404nenalezeno.- Konzistentní struktura chybové odpovědi:
{ "error": "VALIDATION_ERROR", "message": "...", "details": [...] }
Autentizace a autorizace (JWT, session, API klíče)
- JWT: krátká platnost (např. 15 minut), refresh token s rotací; hlavička
Authorization: Bearer <jwt>. - Scopes/role: claims
scopeneborolesv JWT; middlewareauthorize("orders:read"). - API klíče: určené pro server-to-server komunikaci; uložení zahashované, omezení (throttling) dle klíče.
- Session: vhodné pro webové aplikace; preferujte
cookies atributyHttpOnly,SameSite,Secure.
Bezpečnost: CORS, hlavičky, rate-limit, input hardening
- Omezte CORS na whitelist domén a povolte
credentialspouze, pokud je to nezbytné. helmet()upravuje klíčové hlavičky; doplňteCross-Origin-Resource-PolicyaCross-Origin-Opener-Policypodle potřeby.- Rate-limit a zpomalovací strategie pro veřejné endpointy (přihlášení, registrace).
- Sanitace vstupů: validace typů, whitelist polí, prevence NoSQL/SQL injection (parametrizace, whitelist operátorů).
Verzování API a kontrakty
- URI verzování:
/v1/...,/v2/...pro evoluční změny API. - Kontrakty: OpenAPI specifikace (
yaml/json) generuje dokumentaci a slouží ke validaci schémat. - Deprecace: hlavičky
DeprecationaSunsets termínem ukončení a odkazem na migrační návod.
Dokumentace: OpenAPI/Swagger a živé testování
- Generujte OpenAPI specifikace ručně nebo pomocí anotací; publikujte dokumentaci na
/docspouze v chráněném režimu. - Udržujte příklady požadavků, odpovědí a chybových scénářů; doplňte schémata do
components/schemas.
Idempotence, bezpečné opakování a integrace
- Idempotence:
PUTby měl být idempotentní; uPOSTpoužijte idempotency key v hlavičce pro platební či externí operace. - Time-outy a retry: nastavte časová omezení na klientu i serveru; použijte exponenciální backoff.
- Transakce: u SQL databází wrapperem; u DB bez transakcí využijte vzory jako outbox pattern a message broker.
Cacheování, ETag a podmíněné dotazy
- ETag: generujte hash reprezentace zdroje; klient posílá
If-None-Match, server vrací304 Not Modifiedpři nezměněných datech. - Cache-Control: vhodné pro veřejné read-only zdroje; invalidujte cache při změně obsahu.
- Redis: krátkodobá cache opakovaných dotazů, metrik rate-limitu, session store.
Logování, korelace a observabilita
- Strukturované logy: JSON s poli
level,msg,timestamp,requestId. - Correlation ID: middleware generující
request-id(např. zX-Request-IDhlavičky). - Health checks: endpointy
/healthz(základní) a/readyz(závislosti na DB, cache). - Metriky: export do Promethea (latence, požadavky za sekundu, chybovost, využití paměti).
Testování: jednotkové, integrační a kontraktační
- Jednotkové: izolujte služby a repozitáře (mock databáze).
- Integrační:
supertestproti instanciappbez síťového portu; připravte testovací data (seed). - Kontrakty: ověřte shodu s OpenAPI (pact testing, validace schémat).
- Coverage: pokrývejte klíčové scénáře včetně okrajových případů (neplatné vstupy, prázdné výsledky, chybějící oprávnění).
Konfigurace a prostředí
- 12-factor: konfigurace z
process.env, nikoli pevně v kódu. - dotenv: používejte pouze pro lokální vývoj; ve výrobním prostředí získejte tajemství z secret manageru.
- Feature flags: řízení funkcionality bez nutnosti redeploye aplikace.
Výkon a škálování
- Node cluster nebo PM2 pro využití více CPU jader.
- Reverse proxy (NGINX) s keep-alive, gzip/brotli kompresí; TLS terminace.
- Optimalizace DB: správné indexy, omezené SELECTy, projekce polí.
- Horizontální škálování: stateless instance, sticky sessions pouze pokud je to nezbytné.
Nasazení a CI/CD
- Docker: multi-stage build (instalace, build, runtime s
node:alpine), kontejner běžící pod neprivilegovaným uživatelem. - CI: lintování, testování, build image, skenování zranitelností, nasazení do stagingu/produktivního prostředí.
- Migrace: automatické spuštění při startu (Prisma
migrate deploy), strategie rollbacku.
Versioning databáze a evoluce schémat
- Prisma migrations nebo Knex skripty pro SQL; pro MongoDB řízené změny skrze migrační nástroje (Migrate/Mongock).
- Bezpečná evoluce: princip expand–migrate–contract (přidání pole → zapisování do obou verzí → čtení z nové → odstranění starého pole).



























