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 dělá ideální volbu pro síťové služby. Express.js je minimalistický framework, který přidává routing, middleware architekturu a ekosystém rozšíření. Kombinace je vhodná pro RESTful API díky jednoduchosti, výkonu a velké komunitě.
Zásady REST: zdroje, reprezentace, uniformní rozhraní
- Zdroj: doménový objekt (např.
/users,/orders), identifikovaný URI. - Reprezentace: nejčastěji 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ý kontext (autentizace, parametry).
- Hypermedia a odkazy (volitelné): např. pole
_linkss navigací. - Cacheovatelnost: hlavičky
ETag,Cache-Control,Last-Modified.
Struktura projektu: modularita a vrstvy
src/app.js: konfigurace Expressu, middleware, mount routů.src/routes/*.js: definice cest, mapování na kontrolery.src/controllers/*.js: orchestrace požadavků, validace, odpovědi.src/services/*.js: aplikační logika, pravidla domény.src/repositories/*.js: přístup k datům (DB/externí API).src/middlewares/*.js: autentizace, rate-limit, 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áklad:
npm i express dotenv - Bezpečnost a utilitky:
npm i helmet cors morgan express-rate-limit - Validace:
npm i zodnebonpm i joi - Testy:
npm i -D jest supertest - DB (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 src/app.js nastavte jádro: JSON parsování, CORS, bezpečnostní hlavičky, rate-limit a logování.
app.use(express.json({ limit: "1mb" }))– bezpečné parsování těla požadavku.app.use(cors())– řízení původu; ve výrobě omezte na povolené domény.app.use(helmet())– bezpečnostní hlavičky (XSS, clickjacking).app.use(morgan("combined"))– HTTP logy.rateLimit({ windowMs: 60_000, max: 100 })– omezení zneužití.
Routing a kontrolery: čisté oddělení
Route definuje tvar API; kontroler řeší validaci, volá službu a vrací odpověď.
- Příklad cesty:
router.get("/users", userController.list) - Kontroler: načte
req.query(filtr, stránkování), zavoláuserService.findAll, vrátí200s JSON. - Pro vytvoření:
router.post("/users", validate(userSchema), userController.create)
Validace vstupů a sanitace
Validujte query, params i body. Udržujte schémata vedle 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 }); }) - Nechytané chyby/Promises: připojte posluchače
process.on("unhandledRejection")aprocess.on("uncaughtException").
Asynchronní řetězení: async/await a middleware
Zabalte asynchronní kontrolery do helperu, aby nepadaly do unhandled stavů: const asyncH = fn => (req,res,next) => Promise.resolve(fn(req,res,next)).catch(next). Aplikujte na všechny kontrolery.
Persistenční vrstva: Mongoose vs. Prisma
- Mongoose (MongoDB): flexibilní dokumentové modely; rychlý vývoj, schemaless přístup s validací na úrovni modelu.
- Prisma (SQL): typová bezpečnost, migrace, kompozice dotazů; vhodné pro Postgres/MySQL/SQLite.
- Repository pattern:
userRepository.findById(id)kapsuluje detaily DB 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,hasNext, a poleitems. - Indexy: navrhujte podle nejčastějších dotazů; u Mongo využijte
compoundindexy, u SQLbtree/GINdle typu.
Konvence HTTP kódů a odpovědí
200 OKpro čtení,201 Created+ hlavičkaLocationpro vytvoření.204 No Contentpro úspěšnéDELETE.400/422validace,401neautentizovaný,403bez oprávnění,404nenalezeno.- Konzistentní tvar chyby:
{ "error": "VALIDATION_ERROR", "message": "...", "details": [...] }
Autentizace a autorizace (JWT, session, API klíče)
- JWT: krátká expirace (např. 15 min), refresh token s rotací; hlavička
Authorization: Bearer <jwt>. - Scopes/role: claims
scopeneborolesv JWT; middlewareauthorize("orders:read"). - API klíče: pro server-to-server; uložení hashovaně, throttling podle klíče.
- Session: pro webové aplikace; zvážte
cookiesHttpOnly,SameSite,Secure.
Bezpečnost: CORS, hlavičky, rate-limit, input hardening
- Omezte CORS na whitelist domén a použijte
credentialsjen pokud je nutné. helmet()upraví klíčové hlavičky; doplňteCross-Origin-Resource-PolicyaCross-Origin-Opener-Policydle potřeby.- Rate-limit a slowdown pro veřejné endpointy (login, registrace).
- Sanitace vstupů: validace typů, whitelist polí, prevence NoSQL/SQL injection (parametrizace, operátorové whitelisty).
Verzování API a kontrakty
- URI verzování:
/v1/...,/v2/...pro evoluční změny. - Kontrakty: OpenAPI specifikace (
yaml/json) generuje dokumentaci a slouží k validaci schémat. - Deprecation: hlavičky
DeprecationaSunsets termínem ukončení, odkaz na migrační návod.
Dokumentace: OpenAPI/Swagger a živé testování
- Generujte OpenAPI ručně nebo z anotací; publikujte na
/docsjen v chráněném režimu. - Udržujte příklady požadavků/odpovědí a chybové scénáře; doplňte schémata pro
components/schemas.
Idempotence, bezpečné opakování a integrace
- Idempotence:
PUTby měl být idempotentní; proPOSTpoužijte idempotency key v hlavičce pro platební/externí operace. - Time-outs a retry: nastavte klientská i serverová časová omezení; exponenciální backoff.
- Transakce: u SQL wrapujte kritické operace; u DB bez transakcí použijte outbox pattern a message broker.
Cacheování, ETag a podmíněné dotazy
- ETag: generujte hash reprezentace; klient pošle
If-None-Match, server vrátí304 Not Modified. - Cache-Control: pro veřejné read-only zdroje; invalidujte na změnu.
- Redis: krátkodobá cache opakovaných dotazů, rate-limit metriky, session store.
Logování, korelace a observabilita
- Strukturované logy: JSON s poli
level,msg,timestamp,requestId. - Correlation ID: middleware, které generuje
request-id(např. zX-Request-ID). - Health checks:
/healthz(základní),/readyz(závislosti – DB, cache). - Metriky: export do Promethea (latence, RPS, chybovost, využití paměti).
Testování: jednotkové, integrační a kontraktační
- Jednotkové: izolujte služby a repozitáře (mock DB).
- Integrační:
supertestprotiappbez síťového portu; seed testovacích dat. - Kontrakty: ověřte shodu s OpenAPI (pact testing, schema validation).
- Coverage: klíčové happy-path i edge-case (neplatné vstupy, prázdné výsledky, chybějící oprávnění).
Konfigurace a prostředí
- 12-factor: konfigurace z
process.env, nikoli z kódu. - dotenv: pouze pro lokální vývoj; ve výrobě použijte tajemství z secret manageru.
- Feature flags: řízení behavioru bez redeploye.
Výkon a škálování
- Node cluster nebo PM2 pro využití více jader CPU.
- Reverse proxy (NGINX) s keep-alive, gzip/br; TLS terminace.
- DB optimalizace: správné indexy, limitované SELECTy, projekce polí.
- Horizontální škálování: stateless instance, sticky sessions jen pokud nezbytné.
Nasazení a CI/CD
- Docker: multi-stage build (instalace, build, runtime s
node:alpine), neprivilegovaný uživatel. - CI: lint, testy, build image, sken zranitelností, deploy do stagingu/produkce.
- Migrace: automaticky spouštěné při startu (Prisma
migrate deploy), rollback strategie.
Versioning databáze a evoluce schémat
- Prisma migrations nebo Knex skripty pro SQL; pro Mongo řízené změny pomocí migračního nástroje (Migrate/Mongock).
- Bezpečná evoluce: expand–migrate–contract (přidej pole → piš do obou → čti z nového → odstraň staré).
Pozor na časté chyby
- Mixování vrstev (SQL v kontroleru, validace v repozitáři) – porušení separace zodpovědností.
- Nekonzistentní chybové kódy a tvary odpovědí – těžko se debuguje a integruje.
- Chybějící timeouty externích volání – hromadění visících socketů.
- Přehnaně velké payloady – nastavte limity a kompresi.
- Nesprávně nastavené CORS – buď příliš široké (bezpečnost), nebo blokující legitimní klienty.
Checklist před publikací
- Validace všech vstupů, sanitace, limit velikosti těla.
- Jednotný error model a mapování HTTP kódů.
- Autentizace/autorizační middleware na chráněných trasách.
- Rate-limit a
helmetaktivní; CORS výslovně povolené domény. - OpenAPI pokrývá všechny endpointy; verze API uvedena.
- Logy korelované
request-id; healthz/readyz dostupné. - Testy (unit/integration) a automatizované nasazení.
Ukázkové konvence odpovědí
- List:
{ "items": [...], "page": 1, "limit": 20, "total": 134 } - Detail:
{ "id": "...", "name": "...", "_links": { "self": "/v1/users/..." } } - Chyba:
{ "error": "RESOURCE_NOT_FOUND", "message": "User not found" }
Závěr
REST API v Node.js s Express.js těží z jednoduché architektury, bohatého ekosystému a vysoké propustnosti. Dodržujte vrstvovou strukturu, důslednou validaci, jednotné chyby, bezpečnostní zásady a kontraktní dokumentaci. S promyšleným testováním, observabilitou a CI/CD získáte spolehlivou platformu, kterou lze bezpečně a rychle rozvíjet.