Saltar al contenido principal
Version: v2

La API REST

Bien, hasta ahora tiene un frontend que funciona correctamente y algunos todos en su base de datos. Ahora es el momento de codificar una API REST para vincular ambos.

Para ello, va a utilizar un controlador. Los controladores reciben las peticiones HTTP y las procesan. Pueden llamar a servicios en segundo plano para ayudarles a hacerlo. No estudiaremos los servicios en este tutorial.

Abra el archivo api.controller.ts en el directorio src/app/controllers/ y sustituya su contenido.

import { Get, HttpResponseOK } from '@foal/core';

export class ApiController {

@Get('/todos')
getTodos() {
const todos = [
{ id: 1, text: 'My task 1' },
{ id: 2, text: 'My task 2' }
];
return new HttpResponseOK(todos);
}

}

Los controladores tienen métodos especiales que definen las rutas y sus respectivos gestores. Estas funciones están decoradas por uno de los decoradores Get, Post, Patch, Put o Delete que definen el método http y la ruta.

En este caso el controlador responde con un estado 200 y un mock data (los dos falsos todos).

Refresque su navegador, debería ver los dos todos impresos.

Ahora queremos devolver los todos almacenados en la base de datos. Actualice el código como sigue:

import {
Context, Delete, Get, HttpResponseCreated, HttpResponseNoContent,
HttpResponseNotFound, HttpResponseOK, Post
} from '@foal/core';

import { Todo } from '../entities';

export class ApiController {

@Get('/todos')
async getTodos() {
const todos = await Todo.find();
return new HttpResponseOK(todos);
}

}

Si actualiza su navegador, debería ver ahora las tareas que hemos creado a través de la línea de comandos.

Añada las funciones de creación y eliminación.

  @Post('/todos')
async postTodo(ctx: Context) {
// Create a new todo with the body of the HTTP request.
const todo = new Todo();
todo.text = ctx.request.body.text;

// Save the todo in the database.
await todo.save();

// Return the new todo with the id generated by the database. The status is 201.
return new HttpResponseCreated(todo);
}

@Delete('/todos/:id')
async deleteTodo(ctx: Context) {
// Get the todo with the id given in the URL if it exists.
const todo = await Todo.findOne({ id: ctx.request.params.id });

// Return a 404 Not Found response if no such todo exists.
if (!todo) {
return new HttpResponseNotFound();
}

// Remove the todo from the database.
await todo.remove();

// Returns an successful empty response. The status is 204.
return new HttpResponseNoContent();
}

El objeto Context, que se pasa a cada gestor de rutas, contiene el objeto request de Express. Éste representa la petición HTTP y tiene propiedades para leer los parámetros, el cuerpo, las cabeceras HTTP de la petición, etc.

Ahora escriba una nueva tarea en el texto de entrada y pulse Enter. La tarea aparece en la lista de tareas. Actualice la página, debería seguir ahí. Si hace clic en la casilla de verificación, la tarea se ha eliminado con éxito.

Lo último que hay que saber es cómo se vincula el ApiController con el gestor de peticiones. Usted ha definido hasta ahora las rutas en este controlador pero no ha registrado el controlador en ningún sitio. Esto se hace en el archivo app.controller.ts, el punto de entrada de su aplicación.

Abra el archivo app.controller.ts en src/app.

import { controller, IAppController } from '@foal/core';
import { createConnection } from 'typeorm';

import { ApiController } from './controllers';

export class AppController implements IAppController {
subControllers = [
controller('/api', ApiController),
];

async init() {
await createConnection();
}
}

Este controlador es el principal de la aplicación. Se llama directamente cuando entra una solicitud. Puede tener subcontroladores que van en el directorio controllers/.