# Controllers Esta sección del servicio se compone de archivos dentro del directorio `/src/controllers`, cada uno asociado a la ruta que lleva su nombre. Si por ejemplo queremos definir el controlador de `User` que internamente tiene los métodos `getAll` y `update`, el archivo debería llamarse `user.ts` y su código sería: ### Importaciones En primera instancia importamos `express` y `boom`, este último para el manejo de errores. ```typescript import { Request, Response, NextFunction } from 'express'; import boom from "@hapi/boom"; ``` Luego importamos la función que formateará las respuestas del servicio: ```typescript import sendResponse from "../utils/sendResponse"; ``` Se importan los modelos asociados al controlador de forma genérica `*` y se les brinda un alias, para este ejemplo será `User`. ```typescript import * as User from "../models/post"; ``` Finalmente importamos los esquemas que usaremos para validación de entrada (body) en los endpoints (como ejemplo importaremos el esquema `createSchema`): ```typescript import { createSchema } from "../schemas/post"; ``` Como se puede ver, el esquema debe provenir del directorio `/schemas`, el cual dentro debe tener un archivo por cada modelo. ### Estructura de los métodos Los métodos deben ser nombrados por la acción que realizan, puntualmente: - `getAll` trae todos los registros - `getById` trae el registro que coincide con el `id` - `upsert` crea o modifica (según sea el caso) un registro - `deleteById` elimina el registro que coincide con el `id` Obviamente, pueden existir otros métodos que pueden realizar labores más específicas, pero la forma de nombrarlos debe ser semántica, por ejemplo `getByCustomerId` (trae todos los registros cuyo `customer_id` sea el que se indica como parámetro) Deben especificarse el tipo de dato de salida y deben ser asíncronos, para el ejemplo: ```typescript const upsert = async (req: Request, res: Response, next: NextFunction): Promise<void> ``` ### Ejecución del modelo La tarea fundamental del controlador es la ejecución de los modelos, estos últimos al interactuar con la base de datos, deben ser ejecutados asincronicamente: ```typescript const responseUser = await Post.getAll(); ``` ### Retorno de status De existir un error, se debe retornar como status 500 y mencionar el error, el cual normalmente proviene del modelo: ```typescript return next(boom.badImplementation(<error>)); ``` En caso contrario y no hay error en la ejecución se debe formatear el resultado para ser emitido mediante la función `sendResponse`: ```typescript sendResponse(req, res, responseUser); ``` ### Exportación Finalmente se deben exportar los métodos: ```typescript export { getAll, getById, upsert, deleteById }; ``` ### Resultado final El código final resultante sería: ```typescript= // src/routers/post.ts import { Request, Response, NextFunction } from "express"; import boom from "@hapi/boom"; import sendResponse from "../utils/sendResponse"; import * as Post from "../models/post"; import { createSchema } from "../schemas/post"; const getAll = async (req: Request, res: Response, next: NextFunction) => { try { const responsePost = await Post.getAll(); sendResponse(req, res, responsePost); } catch (e: any) { return next(boom.badImplementation(e)); } }; const getById = async ( req: Request, res: Response, next: NextFunction ): Promise<void> => { try { const { id } = req.params; const responsePost = await Post.getById(id); sendResponse(req, res, responsePost); } catch (e: any) { return next(boom.badImplementation(e)); } }; const upsert = async ( req: Request, res: Response, next: NextFunction ): Promise<void> => { try { const { body } = req; const schemaValidate = createSchema.validate(body); if (schemaValidate.error) { return next(boom.badRequest(schemaValidate.error)); } const { user_id, message, image } = schemaValidate.value; const responsePost = await Post.upsert(user_id, message, image); sendResponse(req, res, responsePost); } catch (e: any) { return next(boom.badImplementation(e)); } }; const deleteById = async (req: Request, res: Response, next: NextFunction) => { try { const { id } = req.params; const responsePost = await Post.deleteById(id); sendResponse(req, res, responsePost); } catch (e: any) { return next(boom.badImplementation(e)); } }; export { getAll, getById, upsert, deleteById }; ``` Ver los siguientes documentos: - [**Creación de servicio BackEnd**](https://hackmd.io/@mGoZaVHZQTWgwFlq-J3U0w/B1eLiECDa)<br> - [**Routes**](https://hackmd.io/@mGoZaVHZQTWgwFlq-J3U0w/B1zN9PAPp)<br> - [**Models**](https://hackmd.io/@mGoZaVHZQTWgwFlq-J3U0w/Hy5jcPCvp)<br> - [**Queries**](https://hackmd.io/@mGoZaVHZQTWgwFlq-J3U0w/B1KJswCv6)<br> - [**Schemas**](https://hackmd.io/@mGoZaVHZQTWgwFlq-J3U0w/Syhv28zk0)<br>