LoadCategory e ByPage Controllers no CrazyStack Node.js
Bem-vindo à aula sobre LoadCategory e ByPage Controllers!
Nesta aula, você aprenderá como criar dois importantes controladores em sua aplicação: o LoadCategory Controller e o LoadByPage Controller. Esses controladores são responsáveis por lidar com as requisições relacionadas à categoria, como carregar uma categoria específica e listar categorias por página.
Você aprenderá a usar técnicas como injeção de dependência, criação de fábricas de casos de uso e validações para garantir a consistência e a segurança dos dados. Além disso, você também aprenderá sobre o padrão de projeto Controller, que é uma camada intermediária entre as requisições HTTP e as camadas de negócios de sua aplicação.
Prepare-se para aprender sobre conceitos importantes em desenvolvimento de aplicações e construir controladores poderosos e flexíveis!
Este artigo servirá como uma espécie de documentação de alguns códigos vistos durante as aulas apenas como material complementar.
import {
HttpRequest,
HttpResponse,
Validation,
badRequest,
ok,
} from "@/application/helpers";
import { Controller } from "@/application/infra/contracts";
import { LoadCategory } from "@/slices/category/useCases";
export class LoadCategoryController extends Controller {
constructor(
private readonly validation: Validation,
private readonly loadCategory: LoadCategory
) {
super();
}
async execute(httpRequest: HttpRequest<any>): Promise<HttpResponse<any>> {
const errors = this.validation.validate(httpRequest?.query);
if (errors?.length > 0) {
return badRequest(errors);
}
const categoryLoaded = await this.loadCategory({
fields: httpRequest?.query,
options: {},
});
return ok(categoryLoaded);
}
}
Este é o LoadCategoryController, ele é responsável por carregar categorias de acordo com os campos e opções especificados. Ele usa a classe LoadCategory, que é uma das UseCases criadas para gerenciar as categorias, para obter as informações.
O LoadCategoryController é um tipo de Controller, que é uma camada intermediária entre a camada de roteamento e a camada de negócio. Ele tem a função de validar os dados da requisição, chamar a UseCase, processar a resposta e retornar uma resposta HTTP para o cliente.
A validação é feita através da classe Validation, que verifica se todos os campos necessários para a requisição estão presentes. Se houver algum erro na validação, é retornado um código HTTP 400 (bad request) com a lista de erros.
Se a validação for bem-sucedida, o LoadCategoryController chama a UseCase LoadCategory passando os campos e opções da requisição. O resultado é processado e retornado ao cliente como uma resposta HTTP 200 (ok) com os dados da categoria carregada.
import { makeLogController } from "@/application/decorators/logControllerFactory";
import { makeValidationComposite } from "@/application/factories";
import { Controller } from "@/application/infra/contracts";
import { makeLoadCategoryFactory } from "@/slices/category/useCases";
import { LoadCategoryController } from "@/slices/category/controllers";
export const makeLoadCategoryController = (): Controller => {
const requiredFields = ["_id"];
return makeLogController(
"loadCategory",
new LoadCategoryController(
makeValidationComposite(requiredFields),
makeLoadCategoryFactory()
)
);
};
Este código é uma implementação de um controlador responsável por carregar uma categoria a partir de um id fornecido como parâmetro.
Ele importa diversas funções e classes do pacote "@/application" e "@/slices/category". Em seguida, é definida a classe LoadCategoryController que herda da classe Controller. A classe LoadCategoryController possui uma instância da classe Validation e da função makeLoadCategoryFactory.
A função execute recebe um objeto HttpRequest e retorna uma Promise que, ao ser resolvida, retorna um objeto HttpResponse. A função valida se o id da categoria está presente na query do HttpRequest. Se houver algum erro de validação, a função retorna um objeto HttpResponse com o status code 400 (bad request) e a lista de erros. Caso contrário, a função loadCategory é invocada com o id da categoria e uma lista vazia de opções e o resultado é retornado como um objeto HttpResponse com o status code 200 (ok).
Por fim, é definida a função makeLoadCategoryController que, quando invocada, cria uma instância da classe LoadCategoryController e a envolve com a função makeLogController para habilitar o log de suas invocações. Esta função é útil para fornecer uma instância já configurada do LoadCategoryController a ser utilizada em outras partes do sistema.
import {
HttpRequest,
HttpResponse,
Validation,
badRequest,
ok,
} from "@/application/helpers";
import { Controller } from "@/application/infra/contracts";
import { LoadCategoryByPage } from "@/slices/category/useCases";
export class LoadCategoryByPageController extends Controller {
constructor(
private readonly validation: Validation,
private readonly loadCategoryByPage: LoadCategoryByPage
) {
super();
}
async execute(httpRequest: HttpRequest<any>): Promise<HttpResponse<any>> {
const errors = this.validation.validate(httpRequest?.query);
if (errors?.length > 0) {
return badRequest(errors);
}
const { page, sortBy, typeSort = "asc", ...rest } = httpRequest?.query || {};
const fields = rest;
const sort = { [sortBy]: typeSort === "asc" ? 1 : -1 };
const options = { sort, page };
const categoryLoaded = await this.loadCategoryByPage({
fields,
options,
});
return ok(categoryLoaded);
}
}
Esse é o código de um controlador da aplicação que é responsável por carregar categorias por página. Ele usa a classe LoadCategoryByPageController que é uma subclasse da classe Controller do módulo "@/application/infra/contracts".
O controlador recebe uma requisição HTTP como entrada e retorna uma resposta HTTP. A requisição pode conter consulta na URL e o controlador acessa esta informação através do objeto httpRequest.
O construtor da classe LoadCategoryByPageController recebe duas dependências: a primeira é uma instância da classe Validation e a segunda é uma instância da classe LoadCategoryByPage. As dependências são usadas para validar os dados da requisição e carregar as categorias por página, respectivamente.
O método execute() é chamado para processar a requisição. Nele, os dados da requisição são validados usando a instância da classe Validation. Se houver erros de validação, a função retorna um objeto de resposta HTTP com o status 400 (bad request) e os erros encontrados.
Se não houver erros de validação, o controlador extrai os dados da requisição, como page, sortBy, typeSort, e os campos restantes. Em seguida, ele usa a instância da classe LoadCategoryByPage para carregar as categorias por página. O resultado é retornado como objeto de resposta HTTP com o status 200 (ok).
import { makeLogController } from "@/application/decorators/logControllerFactory";
import { makeValidationComposite } from "@/application/factories";
import { Controller } from "@/application/infra/contracts";
import { makeLoadCategoryByPageFactory } from "@/slices/category/useCases";
import { LoadCategoryByPageController } from "@/slices/category/controllers";
export const makeLoadCategoryByPageController = (): Controller => {
const requiredFields = ["page"];
return makeLogController(
"loadCategoryByPage",
new LoadCategoryByPageController(
makeValidationComposite(requiredFields),
makeLoadCategoryByPageFactory()
)
);
};
Este código é a fábrica que cria o controlador LoadCategoryByPageController
.
A função makeLoadCategoryByPageController
retorna uma instância do Controller
, que é uma interface comum para todos os controladores da aplicação.
A fábrica utiliza o decorador makeLogController
para logar as ações realizadas pelo controlador.
A fábrica também cria a validação dos campos obrigatórios com makeValidationComposite
(nesse caso, apenas o campo "page" é obrigatório).
Por fim, a fábrica instancia o LoadCategoryByPageController
com as dependências já criadas (validação e a fábrica de carregamento de categorias por página), passando as informações para o decorador makeLogController
, que retorna o controlador final.
https://github.com/gumiranda/CrazyStackNodeJs/commit/543020d4f9383c89f0f4aac892fe961086362e6e