Skip to content

Commit 8263828

Browse files
committed
✨feat(catalogo): implementa middleware para validação de entrada de dados | Parte 37
- Refatora o Controller "Atualizar Categoria" para Interceptar Erros e Usar Erros HTTP Apropriados - Refatora o Controller "Deletar Categoria" para Interceptar Erros e Usar Erros HTTP Apropriados - Implementa Classe Específica para Erro HTTP "400 Bad Request" - Implanta "Middleware" Para Validação de Entrada de Dados da Rota "Inserir Categoria" - Melhora Legibilidade dos Erros de Validação da Biblioteca "Zod" - Implanta "Middleware" Para Validação de Entrada de Dados da Rota "Atualizar Categoria"
1 parent 8325c8c commit 8263828

9 files changed

Lines changed: 105 additions & 6 deletions

File tree

package-lock.json

Lines changed: 22 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
"express": "^4.18.2",
5757
"helmet": "^7.1.0",
5858
"morgan": "^1.10.0",
59-
"winston": "^3.11.0"
59+
"winston": "^3.11.0",
60+
"zod": "^3.22.4",
61+
"zod-validation-error": "^2.1.0"
6062
}
6163
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { HttpErrors } from "@shared/presentation/http/http.error";
2+
import { NextFunction, Request, Response } from "express";
3+
import { z, ZodSchema } from "zod";
4+
import { fromZodError } from 'zod-validation-error';
5+
6+
const atualizarCategoriaSchema = z.object(
7+
{
8+
id: z.string().uuid(),
9+
nome: z.string().min(3).max(50)
10+
}
11+
).strict();
12+
13+
const validaInputAtualizarCategoriaMiddleware = (
14+
request: Request,
15+
response: Response,
16+
next: NextFunction) => {
17+
try {
18+
atualizarCategoriaSchema.parse(request.body);
19+
next();
20+
} catch (error: any) {
21+
const validationError = fromZodError(error);
22+
error = new HttpErrors.BadRequestError({message: validationError.message });
23+
next(error);
24+
}
25+
}
26+
27+
export { validaInputAtualizarCategoriaMiddleware as validaInputAtualizarCategoria }
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { HttpErrors } from "@shared/presentation/http/http.error";
2+
import { NextFunction, Request, Response } from "express";
3+
import { z, ZodSchema } from "zod";
4+
import { fromZodError } from 'zod-validation-error';
5+
6+
const inserirCategoriaSchema = z.object(
7+
{
8+
nome: z.string().min(3).max(50)
9+
}
10+
).strict();
11+
12+
const validaInputInserirCategoriaMiddleware = (
13+
request: Request,
14+
response: Response,
15+
next: NextFunction) => {
16+
try {
17+
inserirCategoriaSchema.parse(request.body);
18+
next();
19+
} catch (error: any) {
20+
const validationError = fromZodError(error);
21+
error = new HttpErrors.BadRequestError({message: validationError.message });
22+
next(error);
23+
}
24+
}
25+
26+
export { validaInputInserirCategoriaMiddleware as validaInputInserirCategoria }

src/modules/catalogo/presentation/http/rest/categoria.http

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ POST http://{{host}}:{{port}}/{{apiversion}}/categorias
1313
Content-type: application/json
1414

1515
{
16-
"nome":"Sala de Televisão"
16+
"nome":"Sala"
1717
}
1818

1919
### Atualizar Categoria
20-
PUT http://{{host}}:{{port}}/{{apiversion}}/categorias/ac6c99e0-0759-47c1-89cb-5c6dc6e64852
20+
PUT http://{{host}}:{{port}}/{{apiversion}}/categorias/ac6c99e0-0759-47c1-89cb-5c6dc6e64853
2121
Content-type: application/json
2222

2323
{
@@ -26,4 +26,4 @@ Content-type: application/json
2626
}
2727

2828
### Deletar Categoria
29-
DELETE http://{{host}}:{{port}}/{{apiversion}}/categorias/ac6c99e0-0759-47c1-89cb-5c6dc6e64852
29+
DELETE http://{{host}}:{{port}}/{{apiversion}}/categorias/ac6c99e0-0759-47c1-89cb-5c6dc6e64853

src/modules/catalogo/presentation/http/rest/categoria.routes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import express from 'express';
22
import { atualizarCategoriaController, deletarCategoriaController, inserirCategoriaController, recuperarCategoriaPorIdController, recuperarTodasCategoriasController } from './controllers';
33
import { contentType } from '@main/presentation/http/middlewares/content-type.middleware';
4+
import { validaInputInserirCategoria } from '../middlewares/valida-input-inserir-categoria.middleware';
5+
import { validaInputAtualizarCategoria } from '../middlewares/valida-input-atualizar-categoria.middleware';
46

57
const categoriaRouter = express.Router();
68

@@ -17,12 +19,14 @@ categoriaRouter.get(
1719
categoriaRouter.post(
1820
'/',
1921
contentType,
22+
validaInputInserirCategoria,
2023
(request, response, next) => inserirCategoriaController.inserir(request, response, next)
2124
)
2225

2326
categoriaRouter.put(
2427
'/:id',
2528
contentType,
29+
validaInputAtualizarCategoria,
2630
(request, response, next) => atualizarCategoriaController.atualizar(request, response, next)
2731
)
2832

src/modules/catalogo/presentation/http/rest/controllers/atualizar-categoria.express.controller.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { CategoriaApplicationExceptions } from "@modules/catalogo/application/exceptions/categoria.application.exception";
12
import { AtualizarCategoriaUseCase } from "@modules/catalogo/application/use-cases/atualizar-categoria/atualizar-categoria.use-case";
23
import { RecuperarCategoriaProps } from "@modules/catalogo/domain/categoria/categoria.types";
34
import { ExpressController } from "@shared/presentation/http/express.controller";
5+
import { HttpErrors } from "@shared/presentation/http/http.error";
46
import { NextFunction, Request, Response } from "express";
57

68
class AtualizarCategoriaExpressController extends ExpressController {
@@ -18,6 +20,9 @@ class AtualizarCategoriaExpressController extends ExpressController {
1820
const categoriaAtualizada: boolean = await this._atualizarCategoriaUseCase.execute(categoriaInputDTO);
1921
this.sendSuccessResponse(response,categoriaAtualizada);
2022
} catch (error) {
23+
if (error instanceof CategoriaApplicationExceptions.CategoriaNaoEncontrada){
24+
error = new HttpErrors.NotFoundError({ message: error.message });
25+
}
2126
next(error);
2227
}
2328
}

src/modules/catalogo/presentation/http/rest/controllers/deletar-categoria.express.controller.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { CategoriaApplicationExceptions } from "@modules/catalogo/application/exceptions/categoria.application.exception";
12
import { DeletarCategoriaUseCase } from "@modules/catalogo/application/use-cases/deletar-categoria/deletar-categoria.use-case";
23
import { ExpressController } from "@shared/presentation/http/express.controller";
4+
import { HttpErrors } from "@shared/presentation/http/http.error";
35
import { NextFunction, Request, Response } from "express";
46

57
class DeletarCategoriaExpressController extends ExpressController {
@@ -17,6 +19,9 @@ class DeletarCategoriaExpressController extends ExpressController {
1719
const categoriaDeletada: boolean = await this._deletarCategoriaUseCase.execute(uuid);
1820
this.sendSuccessResponse(response,categoriaDeletada);
1921
} catch (error) {
22+
if (error instanceof CategoriaApplicationExceptions.CategoriaNaoEncontrada){
23+
error = new HttpErrors.NotFoundError({ message: error.message });
24+
}
2025
next(error);
2126
}
2227
}

src/shared/presentation/http/http.error.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,18 @@ class UnsupportedMediaTypeError extends HttpError {
2828
}
2929
}
3030

31+
class BadRequestError extends HttpError {
32+
constructor( params?: {statusCode?: number, message?: string}) {
33+
const { statusCode, message} = params || {};
34+
super(statusCode || 400, message || '⚠️ Servidor Não Pode ou Não Irá Processar a Requisição Devido a Algum Erro do Cliente (ex.: sintaxe de requisição mal formada, enquadramento de mensagem de requisição inválida ou requisição de roteamento enganosa.');
35+
this.name = 'BadRequestError';
36+
}
37+
}
38+
3139
const HttpErrors = {
3240
NotFoundError: NotFoundError,
33-
UnsupportedMediaTypeError: UnsupportedMediaTypeError
41+
UnsupportedMediaTypeError: UnsupportedMediaTypeError,
42+
BadRequestError: BadRequestError
3443
}
3544

3645
export { HttpError, HttpErrors }

0 commit comments

Comments
 (0)