Exemplos

Exemplo — API REST + PostgreSQL

Uma API REST com cara de produção usando Express, PostgreSQL e tratamento adequado de erros.

Estrutura do projeto

my-api/
├── index.js
├── package.json
├── package-lock.json
└── .gitignore

O build de projetos Node.js instala as dependências com npm ci, que exige o package-lock.json. Rode npm install localmente e envie o arquivo gerado junto com o código.

Código

package.json

{
  "name": "my-api",
  "version": "1.0.0",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^5.1.0",
    "pg": "^8.16.0"
  }
}

index.js

const express = require('express');
const { Pool } = require('pg');

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

// A URI do console usa sslmode=verify-full&sslrootcert=system.
// O node-postgres não lê sslrootcert=system; com ssl: true ele valida
// o certificado e o hostname usando as autoridades confiáveis do Node.js.
const databaseUrl = new URL(process.env.DATABASE_URL);
databaseUrl.searchParams.delete('sslmode');
databaseUrl.searchParams.delete('sslrootcert');

const pool = new Pool({
  connectionString: databaseUrl.toString(),
  ssl: true,
});

// Cria tabelas na inicialização
async function initDB() {
  await pool.query(`
    CREATE TABLE IF NOT EXISTS users (
      id SERIAL PRIMARY KEY,
      name TEXT NOT NULL,
      email TEXT UNIQUE NOT NULL,
      created_at TIMESTAMP DEFAULT NOW()
    )
  `);
}

// Rotas
app.get('/users', async (req, res) => {
  const { rows } = await pool.query('SELECT * FROM users ORDER BY created_at DESC');
  res.json(rows);
});

app.get('/users/:id', async (req, res) => {
  const { rows } = await pool.query('SELECT * FROM users WHERE id = $1', [req.params.id]);
  if (rows.length === 0) return res.status(404).json({ error: 'User not found' });
  res.json(rows[0]);
});

app.post('/users', async (req, res) => {
  const { name, email } = req.body ?? {};
  if (!name || !email) return res.status(400).json({ error: 'Name and email required' });

  const { rows } = await pool.query(
    'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
    [name, email]
  );
  res.status(201).json(rows[0]);
});

app.delete('/users/:id', async (req, res) => {
  const { rowCount } = await pool.query('DELETE FROM users WHERE id = $1', [req.params.id]);
  if (rowCount === 0) return res.status(404).json({ error: 'User not found' });
  res.json({ message: 'Deleted' });
});

// Health check
app.get('/health', (req, res) => res.json({ status: 'ok' }));

// O Express 5 encaminha erros de rotas async para este handler
app.use((error, req, res, next) => {
  if (error.code === '23505') return res.status(409).json({ error: 'Email already exists' });
  if (error.code === '22P02') return res.status(400).json({ error: 'Invalid id' });
  console.error(error);
  res.status(500).json({ error: 'Internal server error' });
});

const PORT = process.env.PORT || 3000;
initDB()
  .then(() => {
    app.listen(PORT, '0.0.0.0', () => {
      console.log(`API running on port ${PORT}`);
    });
  })
  .catch((error) => {
    console.error('Database initialization failed', error);
    process.exit(1);
  });

Configuração no console

Crie antes um PostgreSQL gerenciado e copie a URI de conexão. Depois, crie o projeto HTTP com:

CampoValor
Origem do projetoRepositório Git, com Provedor Git GitHub ou Forgejo
RuntimeNode.js, versão 24
Comando Buildvazio
Comando Startnpm start
Porta3000
Variável de ambienteDATABASE_URL com a URI do PostgreSQL

Publicação

  1. Envie o código, incluindo o package-lock.json, para um repositório GitHub ou Forgejo.
  2. No console, escolha Repositório Git em Origem do Projeto e GitHub ou Forgejo em Provedor Git e selecione o repositório.
  3. Selecione a branch principal, em Modo de deploy selecione Automático por branch e crie o projeto.
  4. Faça push na branch para publicar uma nova versão automaticamente.

Teste

Use a URL do projeto em *.clients.zenifra.com para testar as rotas /users.

Respostas esperadas

// POST /users → 201
{ "id": 1, "name": "Alice", "email": "[email protected]", "created_at": "2026-04-30T14:00:00.000Z" }

// GET /users → 200
[ { "id": 1, "name": "Alice", "email": "[email protected]", "created_at": "2026-04-30T14:00:00.000Z" } ]

// GET /users/999 → 404
{ "error": "User not found" }

Próximos exemplos

Última atualização em

Nessa página