# 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>