NodeJS Summary

O Node.js tem um ecossistema rico, mas seus próprios padrões que diferem bastante de linguagens síncronas. O event loop, streams, módulos, padrões assíncronos e o ecossistema npm têm suas próprias regras. Este post cobre os que aparecem repetidamente no desenvolvimento backend real.

TL;DR: Uma referência de Node.js cobrindo event loop, padrões assíncronos, streams, módulos, tratamento de erros e padrões do ecossistema.
Stack: Node.js, JavaScript
Nível: Intermediário
Tempo de leitura: ~15 min

Iniciar o projeto

npm init -y
npm install express typescript @types/express ts-node-dev
npx tsc --init

tsconfig.json mínimo

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true
  }
}

Criar src/index.ts

import express, { Application, Request, Response } from 'express';

const app: Application = express();
const port: number = 3000;

app.get('/', (req: Request, res: Response) => {
  res.send('Olá, mundo!');
});

app.listen(port, () => {
  console.log(`Servidor rodando em http://localhost:${port}`);
});

Adicionar script dev ao package.json

{
  "scripts": {
    "dev": "ts-node-dev src/index.ts"
  }
}
npm run dev

V1 – Rotas (personRoutes.ts)

import { Router } from 'express';
import { ListPerson } from '../../application/useCases/ListPerson/ListPerson';

const personRouter = Router();
const listPersonController = new ListPerson();

personRouter.get('/list-person', async (req, res) => {
  try {
    const people = await listPersonController.handle(req.body);
    res.json(people);
  } catch (error) {
    res.status(500).send('Erro ao listar pessoas');
  }
});

export { personRouter };

V2 – Controllers (ListPersonController.ts)

import { Request, Response } from 'express';

export class ListPersonController {
  async handle(req: Request, res: Response): Promise {
    return res.json({ message: 'Olá, Mundo!' });
  }
}

V3 – Casos de Uso (ListPerson.ts)

import { IListPersonRequest } from "./protocols/IListPersonRequest";
import { IListPersonResponse } from "./protocols/IListPersonResponse";

class ListPerson {
  async handle(inbound: IListPersonRequest): Promise> {
    const returnList: Array = [];
    returnList.push({ name: 'Allan' } as IListPersonResponse);
    returnList.push({ name: 'Maradona' } as IListPersonResponse);
    return returnList;
  }
}

V4 – Repositório com TypeORM

npm install typeorm pg reflect-metadata

Crie o ormconfig.json, adicione o modelo de entidade do TypeORM, implemente o repositório concreto e injete-o no caso de uso pelo controller. O padrão é: controller injeta o repositório no caso de uso, e o caso de uso não sabe com qual banco está falando.

O que você construiu

Um backend Node.js em camadas com controllers, casos de uso e injeção de repositório, cobrindo os padrões que aparecem no código de produção real.

Próximos passos

  • Entenda o event loop: código síncrono o bloqueia, então operações intensivas de CPU devem ir para worker threads ou processos filhos.
  • Use Promise.all() para operações assíncronas independentes em paralelo, e Promise.allSettled() quando precisar dos resultados mesmo que algumas falhem.
  • Nunca chame callback(err, result) de forma síncrona dentro de uma função assíncrona, isso cria bugs sutis de timing.

Dúvidas ou feedback? Me encontre no LinkedIn ou GitHub.

Deixe um comentário