Routing Controller
Javascript

Routing Controllers

02.08.2020 10H00

Rotas do jeito “tradicional”

Normalmente em aplicações construídas com ExpressJS precisamos criar um arquivo (ou arquivos) para definir as rotas, por exemplo:

const express = require('express')
const userController = require('../controllers/userController')

const router = express.Router()

router
  .route('/')
  .get(userController.getAllUsers)
  .post(userController.createUser)

// ...

Neste exemplo as rotas de usuários possui um arquivo próprio e se utiliza do userController e seus métodos, e conforme essa aplicação crescer, mais arquivos de rotas e controllers serão criados para cada módulo, ou seja, dois arquivos para cada módulo.

Porém, um padrão muito utilizado em alguns frameworks é usar apenas o arquivo de controller para definir as rotas, e isso é possível através de annotations ou decorators.

Annotations/Decorators

De uma forma geral, esse recurso consiste em adicionar em seu código uma sintaxe que “intercepta” um método ou classe para manipular seu comportamento. Para utilizarmos esse recurso no ExpressJS precisamos usar typescript e habilitar o uso de decorators no arquivo tsconfig.json, desta forma:

{
    "compilerOptions: {
      // ...
      "experimentalDecorators": true
      "emitDecoratorMetadata": true
      // ...
    }
}

Além disso vamos precisar instalar uma biblioteca chamada Routing Controllers.

Routing Controllers

A biblioteca routing controllers permite usarmos diversos decorators já prontos para implementar o sistema de roteamento de nossa aplicação. Não só isso, mas é possível utilizá-la para validações dos objetos enviados nas requisições, mas falaremos disso em um outro momento.

Enquanto da forma “tradicional” precisávamos de pelo menos dois arquivos por módulo, agora podemos ter apenas um. Seguindo o exemplo anterior, porém usando essa biblioteca nós teríamos algo assim:

import { Request, Response } from 'express'
import { JsonController, Post, Get } from 'routing-controllers'

@JsonController('/users')
export default class UserController {
  @Post()
  public async create() {
    // ...
  }

  @Get()
  public async getAll() {
    // ...
  }
}

Viu, que simples?! O decorator @JsonController usado acima da classe determina o prefixo de todas as rotas do arquivo, enquanto o @Post e @Get representa os verbos HTTP (podem conter também sufixos caso necessário).

Caso tenha interesse no processo de configuração e queira um exemplo mais completo, confira esse template onde foi utilizado esse padrão juntamento com MongoDB.

Criador do blog SourceVortex, apaixonado em distribuições Linux e por aprender novas tecnologias, buscando também sempre aperfeiçoar os conhecimentos já obtidos.