API Node Desacoplada: Criando os AdaptRouter para o Express e o Fastify
Zoranildo Santos
Posted on August 1, 2023
Neste artigo vamos criar os adaptadores de rota para o express
e para o fastify
. Com isso nossa aplicação finalmente será capaz de funcionar com express ou fastify, apenas alterando o valor da variável SERVER_TYPE
no arquivo .env
.
Dentro da pasta infra
crie uma nova pasta chamada adapter
. Dentro da pasta adapter crie dois arquivos adaptRouteFastify.ts
e adaptRouteExpress.ts
.
Criando o adaptador para o Express
No arquivo adaptRouteExpress.ts
insira o código abaixo:
import { Request, Response } from 'express'
import { HttpRequest } from '../shared/protocols/http'
import { IController } from '../shared/protocols/controller'
export const adaptRouteExpress = (controller: IController) => {
// A função adaptRouteExpress é exportada para que possa ser
// utilizada em outros módulos da aplicação. Ela recebe um
// parâmetro controller, que é uma instância da classe que
// implementa a interface IController.
return async (req: Request, res: Response) => {
// Retorna uma função assíncrona que será utilizada como
// callback para o roteamento no Express.js. A função callback
// recebe os parâmetros req (requisição) e res (resposta) do
// Express.js.
const httpRequest: HttpRequest = {
body: req.body
}
// Estamos adaptando a estrutura de dados da requisição
// recebida pelo Express.js para o formato esperado pela
// interface HttpRequest. Neste caso, estamos apenas pegando o
// corpo da requisição (req.body) e atribuindo ao campo body
// do objeto httpRequest.
const httpResponse = await controller.handle(httpRequest)
res.status(httpResponse.statusCode).json(httpResponse.body)
// A resposta obtida do controller é adaptada para o formato
// esperado pelo Express.js. Utilizamos os métodos status e
// json do objeto res para definir o status code HTTP da
// resposta e enviar o corpo no formato JSON para o client.
}
}
Agora precisamos utilizar o adapter criado. No arquivo signUp.routes.ts
faça as alteração necessárias para ultilizar o adaptador:
Antes:
import { Router } from 'express'
import { CreateSignUpFactory } from '../../../application/modules/SignUp/useCases/CreateSignUp/CreateSignUpFactory'
const signupRoutes = Router()
signupRoutes.post('/signup', (req, res) => CreateSignUpFactory().handle(req, res))
export { signupRoutes }
Depois:
import { Router } from 'express'
import { CreateSignUpFactory } from '../../../application/modules/SignUp/useCases/CreateSignUp/CreateSignUpFactory'
import { adaptRouteExpress } from '../../../infra/adapters/adaptRouteExpress'
const signupRoutes = Router()
signupRoutes.post('/signup', adaptRouteExpress(CreateSignUpFactory()))
export { signupRoutes }
Criando o adaptador para o Fastify
No arquivo adaptRouteFastify.ts
insira o código abaixo:
Aqui a estrutura é a mesma com uma pequena diferença: a tipagem usada é a do fastify naturalmente.
import { FastifyRequest, FastifyReply } from 'fastify'
import { HttpRequest } from '../shared/protocols/http'
import { IController } from '../shared/protocols/controller'
export const adaptRouteFastify = (controller: IController) => {
return async (req: FastifyRequest, res: FastifyReply) => {
const httpRequest: HttpRequest = {
body: req.body
}
const httpResponse = await controller.handle(httpRequest)
res.status(httpResponse.statusCode).send(httpResponse.body)
}
}
Agora precisamos utilizar o adapter criado. No arquivo index.ts
que fica dentro da pasta fastify
responsável pelas rotas(src/infra/routes/fastify/index.ts) faça as alteração necessárias para ultilizar o adaptador:
Antes:
import { FastifyPluginAsync } from 'fastify'
import { CreateSignUpFactory } from '../../../application/modules/SignUp/useCases/CreateSignUp/CreateSignUpFactory'
export const signUpRouter: FastifyPluginAsync = async (
fastify
): Promise<void> => {
fastify.post('/signup', (req, res) => CreateSignUpFactory().handle(req, res))
}
Depois:
import { FastifyPluginAsync } from 'fastify'
import { CreateSignUpFactory } from '../../../application/modules/SignUp/useCases/CreateSignUp/CreateSignUpFactory'
import { adaptRouteFastify } from '../../../infra/adapters/adaptRouteFastify'
export const signUpRouter: FastifyPluginAsync = async (
fastify
): Promise<void> => {
fastify.post('/signup', adaptRouteFastify(CreateSignUpFactory()))
}
Testando a aplicação
Agora que já temos os adaptadores das rotas podemos testar se nossa aplicação vai funcionar tanto com Express
quanto com Fastify
.
Testando com Express
Coloque o valor express
para a variável SERVER_TYPE
no arquivo .env
SERVER_TYPE=express
PORT_SERVER=5000
Execute o comando yarn start:dev
no terminal. Teste a requisição no insomnia ou qualquer outra ferramenta, se tudo estiver correto teremos esse resultado:
O status code retornado é o 201 que foi definido na função create no arquivo httpHelper.ts
o body stá vázio porque não definimos mensagem de criação bem sucedida.
Testando com Fastify
Pare a aplicação e altere o valor da variável SERVER_TYPE
para fastify(no arquivo .env
).
Execute novamente o comando yarn start:dev
no terminal. Teste a requisição no insomina ou qualquer outra ferramenta. O resultado obtido deverá ser o mesmo do anterior demonstrado no print acima.
Conclusão
Como prometido temos agora uma aplicação que funciona tanto com fastify
quanto com express
mudando apenas uma variável de ambiente(SERVER_TYPE
), sem ser necessário alterar nosso código principal. Nossa camada de domínio(entidades e usecases dentro da pasta aplication
) não precisa saber que ferramentas externas estamos usando, isso não interessa.
Se quisermos usar outro framework que não o express ou o fastify não será necessário alterar código na nossa camada de domínio, apenas na camada de infraestrutura.
Ainda temos alguma coisas pra melhorar na nossa aplicação que será feito nos próximos artigos. Até breve.
Posted on August 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.