Menu

Servidor HTTP no Node.js: http.createServer com exemplos

http.createServer() recebe uma função que roda a cada requisição com req e res. Você lê o método e a URL de req, define status, headers e body em res e chama res.end().

Esta página tem editores executáveis. Edite, execute e veja a saída na hora.

http.createServer() cria um servidor web a partir de uma função, o request handler, que o Node chama a cada requisição recebida com dois objetos: req (o método, a URL e os headers que o cliente enviou) e res (o que você devolve). Defina um status code e headers em res, depois chame res.end() com o body. server.listen(3000) começa a aceitar conexões na porta 3000.

A primeira requisição responde You asked for GET /hello?name=Ada, e o Console registra o mesmo método e a mesma URL. Envie DELETE /anything pela barra de requisição: o mesmo handler responde, porque um servidor http puro não tem rotas. Toda requisição passa pela única função.

Enviar JSON e definir o status code

res.writeHead(status, headers) define o status code e os headers em uma chamada. Para JSON, defina Content-Type: application/json e envie o resultado de JSON.stringify(); res.end() só aceita string ou Buffer.

GET /users?limit=1 retorna [{"id":1,"name":"Ada"}]. req.url é o caminho mais a query string, então new URL(req.url, 'http://localhost') separa em pathname e searchParams (a base só está ali porque URL precisa de um endereço absoluto). Envie GET /nothing e o status vira 404.

Rotas com um switch

Uma API pequena não precisa de mais que um switch no método e no caminho. Monte uma chave como 'GET /users' e dê a cada rota o seu próprio case:

Envie POST /users com o body {"name": "Grace"}: a resposta é 201 com {"id":2,"name":"Grace"}, e GET /users agora lista os dois usuários. Envie o mesmo POST com o body hello e você recebe 400 com {"error":"Body must be JSON"}.

Ler o body de um POST

O Node não interpreta o body por você. req é uma readable stream, e o body chega em pedaços pelos eventos data, depois end dispara quando ele está completo. O readBody() acima junta os pedaços em uma string e retorna uma promise, para o handler poder dar await. Como req é async iterable, este loop faz o mesmo trabalho:

let data = '';
for await (const chunk of req) data += chunk;
const body = JSON.parse(data);

Um servidor real também limita o tamanho (para de ler e responde 413 quando data.length passa de um limite) e confere req.headers['content-type'] antes de chamar JSON.parse.

Erros comuns

Esquecer o res.end(). Um caminho do código que define um status mas nunca encerra a resposta deixa o cliente esperando até dar timeout.

Definir um header depois do body. Depois que res.end() ou o primeiro res.write() rodou, os headers já foram enviados, e res.setHeader() lança ERR_HTTP_HEADERS_SENT. Use return quando enviar uma resposta antes do fim, como os exemplos fazem.

Comparar req.url com um caminho. req.url inclui a query string, então req.url === '/users' é falso para /users?limit=1. Compare o pathname.

Quando usar Express

O módulo http basta para um health check, um receptor de webhooks ou para aprender como o HTTP funciona. Quando você precisa de parâmetros de rota como /users/:id, parse de body JSON, middleware e tratamento de erros, acaba escrevendo seu próprio framework pequeno. O Express é esse framework, construído sobre os mesmos objetos req e res; o roteamento no Express mostra a mesma API com app.get() e app.post().

Perguntas frequentes

Qual a diferença entre res.write e res.end?

res.write() envia um pedaço do body e mantém a resposta aberta, então você pode chamar várias vezes. res.end() envia um último pedaço opcional e encerra a resposta. Toda resposta precisa de exatamente um res.end().

Como paro um servidor HTTP do Node?

Chame server.close(). Ele para de aceitar conexões novas na hora e roda o callback quando as abertas terminam, que é o que um desligamento limpo no SIGTERM precisa.

Como uso HTTPS com o módulo http?

Use o módulo https: https.createServer({ key, cert }, handler) recebe o mesmo handler mais uma chave privada e um certificado. Em produção, normalmente um proxy como o Nginx ou a plataforma de hospedagem termina o TLS, e seu servidor Node continua escutando em HTTP simples.

Em que porta um servidor Node deve escutar?

Qualquer porta livre acima de 1024 funciona sem permissão de admin; 3000 e 8080 são comuns em desenvolvimento. As plataformas de hospedagem geralmente informam a porta em uma variável de ambiente, então escreva server.listen(process.env.PORT || 3000).

Ilustração das linguagens de programação do Coddy

Aprenda a programar com o Coddy

Começar