Un servicio
Parte de la sección TypeScript y NestJS del Journey de Node.js de Coddy. Lección 9 de 24.
El controlador contiene las tareas, así que ninguna otra parte de la aplicación puede acceder a ellas. Los datos y la lógica pertenecen a un proveedor: una clase que Nest crea y entrega a quien la solicita.
@Injectable()
export class BooksService {
private books = [{ title: 'Dune' }];
}
@Controller('books')
export class BooksController {
constructor(private readonly booksService: BooksService) {}
}@Injectable() marca la clase, y el módulo la incluye en providers. Una clase la solicita nombrándola en su constructor: esto es inyección de dependencias. private readonly delante del parámetro es una abreviatura de TypeScript: crea un campo this.booksService y almacena lo que Nest le pasa. Nest lee el tipo del parámetro, que el compilador conserva para las clases decoradas, crea una instancia para el módulo que la incluye y pasa esa misma instancia a todas las clases de ese módulo que la solicitan. Los datos se comparten, y una prueba puede pasar una instancia simulada en su lugar.
Esta lección comienza con el controlador ya llamando a this.tasksService.
Desafío
FácilEste paso abre el proyecto preparado del rastreador de tareas de Nest del curso, en lugar de los archivos de tu proyecto de Códigos de estado y errores (incluido src/tasks/tasks.controller.ts). Tu trabajo anterior permanece en su propia lección. Lee los archivos proporcionados antes de editar src/tasks/tasks.service.ts. Esta copia contiene las rutas de tareas de Nest, con el controlador preparado para delegar en un servicio.
Las tareas están dentro del controlador, así que ninguna otra parte de la aplicación puede acceder a ellas. Muévelas a un servicio: una clase que se encarga de las tareas, que Nest crea una vez y entrega a cada clase que lo solicita. El controlador ya se reescribió para llamar al servicio. Tu tarea es terminar el servicio y conectar ambos.
- En
src/tasks/tasks.service.ts, marca la claseTasksServicecon@Injectable(), de@nestjs/common. Esto permite que Nest la cree y la entregue. - En la misma clase, escribe un método
create(title). Este crea una tarea con el siguiente id disponible (uno más que el id más grande dethis.tasks), ese título ydone: false. Añade la tarea athis.tasksy la devuelve. El controlador llama a este método desdePOST /tasks, con el título del cuerpo de la solicitud. - Escribe un método
remove(id), dondeides un número. Si ninguna tarea tiene ese id, debe responder con 404, comofindOne: primero llama athis.findOne(id), que lanza una excepción. Después, elimina la tarea dethis.tasks. No devuelve nada. - En
src/tasks/tasks.module.ts, importaTasksServicedesde./tasks.service; luego añade una listaprovidersal módulo, junto acontrollers, e incluyeTasksServiceen ella. Nest solo crea las clases que un módulo enumera allí. - En
src/tasks/tasks.controller.ts, reemplaza el comentario dentro deTasksControllerpor un constructor que tome un parámetro, escritoprivate readonly tasksService: TasksService. Nest ve el tipoTasksServicey pasa su único servicio. Las palabrasprivate readonlydelante de un parámetro también crean un campo,this.tasksService, que contiene lo que se pasó. Ese es el nombre que ya usan los métodos siguientes.
Pruébalo: envía POST { "title": "Buy milk" } a /tasks. Obtendrás 201 y:
{ "id": 4, "title": "Buy milk", "done": false }Envía GET /tasks: cuatro tareas, con Buy milk al final. Envía DELETE /tasks/4: 204. Envía DELETE /tasks/99: 404 con "message": "Task 99 not found".
Pruébalo tú mismo
import { NotFoundException } from '@nestjs/common';
export interface Task {
id: number;
title: string;
done: boolean;
createdAt?: string;
}
// Haz que esta clase sea un proveedor que Nest pueda inyectar.
export class TasksService {
private tasks: Task[] = [
{ id: 1, title: 'Write the README', done: true, createdAt: '2026-01-05T09:00:00.000Z' },
{ id: 2, title: 'Fix the login bug', done: false, createdAt: '2026-01-06T14:30:00.000Z' },
{ id: 3, title: 'Plan the sprint', done: false, createdAt: '2026-01-07T08:15:00.000Z' },
];
findAll(done?: string): Task[] {
if (done === undefined) {
return this.tasks;
}
return this.tasks.filter((task) => task.done === (done === 'true'));
}
findOne(id: number): Task {
const task = this.tasks.find((task) => task.id === id);
if (!task) {
throw new NotFoundException(`Task ${id} not found`);
}
return task;
}
// Escribe create(title) y remove(id) aquí.
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de TypeScript y NestJS
1Fundamentos de Nest
Clases y métodosHola, NestRegistro de un controlador4Guards, filtros e interceptores
Guards2Proveedores
Entradas del constructorUn servicioRegistro de proveedoresPractica por tu cuenta: Playground de Express