Um serviço
Parte da seção TypeScript e NestJS do Journey de Node.js da Coddy. Lição 9 de 24.
O controlador mantém as próprias tarefas, então nenhuma outra parte do app pode acessá-las. Os dados e a lógica pertencem a um provedor: uma classe que o Nest cria e entrega a quem o solicita.
@Injectable()
export class BooksService {
private books = [{ title: 'Dune' }];
}
@Controller('books')
export class BooksController {
constructor(private readonly booksService: BooksService) {}
}@Injectable() marca a classe, e o módulo a lista em providers. Uma classe solicita o provedor ao nomeá-lo em seu construtor: isso é injeção de dependência. private readonly antes do parâmetro é um atalho do TypeScript: ele cria um campo this.booksService e armazena nele o que o Nest passa. O Nest lê o tipo do parâmetro, que o compilador mantém para classes decoradas, cria uma instância para o módulo que o lista e passa essa mesma instância a todas as classes desse módulo que a solicitam. Os dados são compartilhados, e um teste pode passar uma instância falsa no lugar.
Esta lição começa com o controlador já chamando this.tasksService.
Desafio
FácilEsta etapa abre o projeto preparado de rastreador de tarefas em Nest do curso, em vez dos arquivos do seu projeto de Códigos de status e erros (incluindo src/tasks/tasks.controller.ts). Seu trabalho anterior continua na própria lição. Leia os arquivos fornecidos antes de editar src/tasks/tasks.service.ts. Esta cópia contém as rotas de tarefas do Nest, com o controller preparado para delegar a um serviço.
As tarefas ficam dentro do controller, então nenhuma outra parte do app pode acessá-las. Mova-as para um serviço: uma classe que é responsável pelas tarefas e que o Nest cria uma vez e entrega a toda classe que a solicita. O controller já foi reescrito para chamar o serviço. Sua tarefa é concluir o serviço e conectar os dois.
- Em
src/tasks/tasks.service.ts, marque a classeTasksServicecom@Injectable(), de@nestjs/common. Isso permite que o Nest a crie e a disponibilize. - Na mesma classe, escreva um método
create(title). Ele cria uma tarefa com o próximo id disponível (um a mais que o maior id emthis.tasks), esse título edone: false. Ele adiciona a tarefa athis.taskse a retorna. OPOST /tasksdo controller o chama com o título do corpo da requisição. - Escreva um método
remove(id), em queidé um número. Quando nenhuma tarefa tiver esse id, ele deve responder com 404, comofindOne: chamethis.findOne(id)primeiro, o que lança uma exceção. Em seguida, remova a tarefa dethis.tasks. Ele não retorna nada. - Em
src/tasks/tasks.module.ts, importeTasksServicede./tasks.servicee, em seguida, adicione uma listaprovidersao módulo, ao lado decontrollers, e incluaTasksServicenela. O Nest só cria as classes listadas ali por um módulo. - Em
src/tasks/tasks.controller.ts, substitua o comentário dentro deTasksControllerpor um construtor que receba um parâmetro, escrito comoprivate readonly tasksService: TasksService. O Nest identifica o tipoTasksServicee passa seu serviço único. As palavrasprivate readonlyantes de um parâmetro também criam um campo,this.tasksService, que armazena o valor recebido. Esse é o nome que os métodos abaixo já usam.
Experimente: envie POST { "title": "Buy milk" } para /tasks. Você recebe 201 e:
{ "id": 4, "title": "Buy milk", "done": false }Envie GET /tasks: quatro tarefas, com Buy milk por último. Envie DELETE /tasks/4: 204. Envie DELETE /tasks/99: 404 com "message": "Task 99 not found".
Experimente você mesmo
import { NotFoundException } from '@nestjs/common';
export interface Task {
id: number;
title: string;
done: boolean;
createdAt?: string;
}
// Transforme esta classe em um provider que o Nest possa injetar.
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;
}
// Escreva create(title) e remove(id) aqui.
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de TypeScript e NestJS
1Fundamentos do Nest
Classes e métodosOlá, NestRegistrando um controller4Guardas, filtros e interceptadores
Guardas2Provedores
Entradas do construtorUm serviçoRegistrando provedoresPratique por conta própria: Playground de Express