http.createServer în Node.js

Pornește un server web cu modulul de bază node:http: primești cererea (req) și trimiți răspunsul (res).

Sintaxă
import http from "node:http";
const server = http.createServer((req, res) => {
  res.writeHead(200, { "content-type": "text/plain; charset=utf-8" });
  res.end("text");
});
server.listen(port);

Ce face http.createServer

http.createServer(handler) creează un server; server.listen(port) îl pornește. Pentru fiecare cerere este apelată funcția handler(req, res). Din req citești metoda (req.method), adresa (req.url, de exemplu "/produse?oras=Iasi") și antetele (req.headers, cu nume scrise cu litere mici).

Răspunsul îl construiești cu res.writeHead(cod, antete) (sau res.statusCode și res.setHeader), apoi res.end(conținut). Fără res.end() clientul așteaptă la nesfârșit. Corpul unei cereri POST vine ca stream: îl citești cu for await (const bucata of req).

node:http este nivelul de bază peste care sunt construite Express, Fastify și altele. Pentru o aplicație reală vei folosi de obicei un astfel de framework, dar modulul este suficient pentru un API mic sau pentru teste. server.close() oprește serverul (din Node.js 19 închide și conexiunile inactive).

Parametri

Parametru Descriere
handler(req, res) Funcția apelată la fiecare cerere.
server.listen(port, [gazdă]) Pornește ascultarea. Portul 0 alege un port liber.
res.writeHead(cod, antete) Codul de stare și antetele răspunsului.
res.end([date]) Trimite ultima parte și încheie răspunsul.
server.close() Oprește serverul.

Ce returnează

Un obiect http.Server (este și EventEmitter).

Exemple

Exemplul 1: Un API mic, pornit și testat în același script

Serverul ascultă pe portul 0 (un port liber ales de sistem), primește trei cereri cu fetch, apoi se oprește. Așa exemplul se termină singur.

import http from "node:http";
import { once } from "node:events";

const produse = [{ id: 1, nume: "mere", pret: 4.5 }, { id: 2, nume: "pere", pret: 6 }];

const server = http.createServer((req, res) => {
  const url = new URL(req.url, "http://localhost");
  if (req.method === "GET" && url.pathname === "/produse") {
    res.writeHead(200, { "content-type": "application/json; charset=utf-8" });
    return res.end(JSON.stringify(produse));
  }
  res.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
  res.end(`Nu există: ${url.pathname}`);
});

server.listen(0);
await once(server, "listening");
const baza = `http://localhost:${server.address().port}`;

const r1 = await fetch(`${baza}/produse`);
console.log(r1.status, r1.headers.get("content-type"), await r1.json());

const r2 = await fetch(`${baza}/cos`);
console.log(r2.status, await r2.text());

server.close();

Rezultat

200 application/json; charset=utf-8 [
  { id: 1, nume: 'mere', pret: 4.5 },
  { id: 2, nume: 'pere', pret: 6 }
]
404 Nu există: /cos

Exemplul 2: Citirea corpului unei cereri POST

import http from "node:http";
import { once } from "node:events";

const server = http.createServer(async (req, res) => {
  let corp = "";
  for await (const bucata of req) corp += bucata;
  const comanda = JSON.parse(corp);
  const total = comanda.produse.reduce((s, p) => s + p.pret * p.cantitate, 0);
  res.writeHead(201, { "content-type": "application/json" });
  res.end(JSON.stringify({ client: comanda.client, total }));
});

server.listen(0);
await once(server, "listening");

const raspuns = await fetch(`http://localhost:${server.address().port}/comenzi`, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ client: "Ana", produse: [{ pret: 12.5, cantitate: 2 }, { pret: 30, cantitate: 1 }] }),
});
console.log(raspuns.status, await raspuns.json());
server.close();

Rezultat

201 { client: 'Ana', total: 55 }

Exemplul 3: Server pornit din terminal

Un server obișnuit rulează până îl oprești cu Ctrl+C. Deschide în browser http://localhost:3000/.

// server.mjs
import http from "node:http";

const port = Number(process.env.PORT ?? 3000);
http.createServer((req, res) => {
  res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
  res.end("<h1>Bun venit la magazinul din Iași</h1>");
}).listen(port, () => console.log(`Server pornit pe http://localhost:${port}`));

// în terminal: node server.mjs

Ieșire în terminal

Server pornit pe http://localhost:3000

Greșeli frecvente

  • Uiți res.end() pe una dintre ramuri (de exemplu la 404): browserul se învârte până expiră cererea.
  • Trimiți text cu diacritice fără charset=utf-8 în content-type: browserul poate afișa „IaÈ™i”.
  • Pornești serverul pe un port ocupat și primești EADDRINUSE. Oprește celălalt proces, alege alt port sau folosește portul 0 în teste.
  • Apelezi res.writeHead după ce ai trimis deja date (res.write): antetele au plecat, iar Node.js aruncă ERR_HTTP_HEADERS_SENT.

Comenzi înrudite

  • EventEmitter (node:events): Clasa pentru evenimente din Node.js: înregistrezi ascultători cu on și îi declanșezi cu emit. Baza pentru stream-uri și servere.
  • stream.Readable: Stream-ul din care citești date bucată cu bucată: fișiere, cereri HTTP, stdin. Readable.from îl creează din orice iterabil.
  • node --watch: Repornește automat scriptul când salvezi fișierul sau unul dintre modulele importate, fără nodemon.
  • process.env: Obiectul cu variabilele de mediu ale procesului: configurări ca PORT, NODE_ENV sau chei de API, mereu ca șiruri.
  • node:sqlite (DatabaseSync): Baza de date SQLite inclusă în Node.js, fără pachete: creezi tabele, inserezi și citești rânduri cu interogări pregătite.