Guias por framework

APIs Node.js com Express, Fastify e NestJS

Este guia cobre APIs e backends Node.js publicados pelo Repositório GitHub. A Zenifra instala as dependências com npm ci, executa a build quando configurada e inicia a aplicação com o comando start.

Pré-requisitos

Escutando na porta certa

Leia a porta de uma variável com valor padrão e escute em 0.0.0.0:

index.js
const express = require('express');

const app = express();
app.use(express.json());

app.get('/health', (req, res) => res.json({ status: 'ok' }));
app.get('/', (req, res) => res.json({ message: 'Olá da Zenifra' }));

const port = Number(process.env.PORT ?? 3000);
app.listen(port, '0.0.0.0', () => console.log(`Escutando na porta ${port}`));

O campo Porta do projeto deve ter o mesmo valor. Se não definir a variável PORT, o padrão 3000 do código é usado.

Valores para o console

Projetobuildstart
Express ou Fastify em JavaScriptvazionode index.js
Express ou Fastify em TypeScriptnpm run buildnode dist/index.js
NestJSnpm run buildnode dist/main.js

Use Porta 3000 nos três casos, ou a porta que o código usar.

Sem build, sem devDependencies

Quando o campo build fica vazio, as devDependencies são removidas antes de a aplicação iniciar. Tudo o que o start usa em execução precisa estar em dependencies. Não use ts-node, tsx ou nodemon no start de produção: compile na build e rode o JavaScript gerado.

NestJS

O NestJS compila para dist/ com nest build. Confirme o script:

package.json
{
  "scripts": {
    "build": "nest build",
    "start:prod": "node dist/main.js"
  }
}

O @nestjs/cli pode ficar em devDependencies, porque a build roda com elas instaladas quando o campo build está preenchido.

Para health check com dependências, o pacote @nestjs/terminus expõe uma rota pronta. Mantenha a rota rápida: o health check roda a cada minuto e reinicia a instância em caso de falha.

Migrations

As variáveis do projeto, incluindo DATABASE_URL, existem tanto na build quanto na execução. O jeito mais previsível é aplicar migrations no início do start:

start: npx prisma migrate deploy && node dist/main.js

A ferramenta usada no start precisa estar instalada em execução: em dependencies, ou em devDependencies quando o campo build está preenchido.

Encerramento gracioso

Em cada publicação ou reinício, a instância antiga recebe o sinal SIGTERM. Feche conexões e termine requisições em andamento:

process.on('SIGTERM', () => {
  server.close(() => process.exit(0));
});

No NestJS, app.enableShutdownHooks() faz isso por você.

WebSockets e Server-Sent Events

Conexões WebSocket e SSE funcionam pela mesma porta HTTP do projeto, inclusive em domínios personalizados. Com várias instâncias, cada conexão fica em uma instância: para enviar mensagens a todos os clientes, use um canal compartilhado, como o cache gerenciado com pub/sub.

Workers e filas

Processos em segundo plano, como consumidores de fila, podem rodar como um projeto separado com o próprio comando start. Veja o exemplo de worker Python e as filas gerenciadas. Se quiser usar o health check em um worker, exponha uma rota /health mínima na porta do projeto.

Problemas comuns

SintomaCorreção
Error: listen EADDRINUSEDois servidores tentando a mesma porta. Inicie apenas um processo no start
URL pública não responde, logs sem erroServidor escutando em localhost. Use 0.0.0.0
Cannot find module 'dist/main.js'Campo build vazio ou outDir diferente no tsconfig.json
Cannot find module 'ts-node'Compile na build e rode o JavaScript
Erro de CORS no navegadorConfigure o domínio do front-end na origem permitida do CORS

Próximos passos

Última atualização em

Nessa página