Usługa
Część sekcji TypeScript i NestJS ścieżki Node.js w Coddy. Lekcja 9 z 24.
Kontroler przechowuje zadania, więc żadna inna część aplikacji nie może uzyskać do nich dostępu. Dane i logika należą do dostawcy: klasy, którą Nest tworzy i przekazuje każdemu, kto o nią poprosi.
@Injectable()
export class BooksService {
private books = [{ title: 'Dune' }];
}
@Controller('books')
export class BooksController {
constructor(private readonly booksService: BooksService) {}
}@Injectable() oznacza klasę, a moduł wymienia ją w providers. Klasa prosi o nią, podając jej nazwę w konstruktorze: to wstrzykiwanie zależności. private readonly przed parametrem to skrót w TypeScript: tworzy pole this.booksService i zapisuje w nim to, co przekazuje Nest. Nest odczytuje typ parametru, który kompilator zachowuje dla dekorowanych klas, tworzy jedną instancję dla modułu, który ją wymienia, i przekazuje tę samą instancję każdej klasie w tym module, która o nią poprosi. Dane są współdzielone, a test może zamiast tego przekazać atrapę.
Ta lekcja rozpoczyna się od kontrolera, który już wywołuje this.tasksService.
Wyzwanie
ŁatwyTen krok otwiera przygotowany w ramach kursu projekt menedżera zadań Nest, a nie pliki projektu z lekcji Kody stanu i błędy (w tym src/tasks/tasks.controller.ts). Twoja wcześniejsza praca pozostaje w osobnej lekcji. Przed edycją src/tasks/tasks.service.ts przeczytaj dostarczone pliki. Ta kopia zawiera trasy zadań Nest, a kontroler jest przygotowany do przekazywania obsługi do usługi.
Zadania znajdują się w kontrolerze, więc żadna inna część aplikacji nie ma do nich dostępu. Przenieś je do usługi: klasy, która zarządza zadaniami, a którą Nest tworzy raz i przekazuje każdej klasie, która o nią poprosi. Kontroler został już przepisany tak, by wywoływał usługę. Twoim zadaniem jest dokończenie usługi i połączenie tych dwóch elementów.
- W
src/tasks/tasks.service.tsoznacz klasęTasksServicedekoratorem@Injectable()z pakietu@nestjs/common. Dzięki temu Nest może ją utworzyć i przekazywać dalej. - W tej samej klasie napisz metodę
create(title). Tworzy ona zadanie z kolejnym wolnym identyfikatorem (o jeden większym od największego identyfikatora wthis.tasks), podanym tytułem i wartościądone: false. Dodaje zadanie dothis.tasksi je zwraca. Kontroler wywołuje ją dlaPOST /tasks, przekazując tytuł z treści żądania. - Napisz metodę
remove(id), w którejidjest liczbą. Jeśli nie ma zadania o takim identyfikatorze, metoda musi zwrócić 404, tak jakfindOne: najpierw wywołajthis.findOne(id), która zgłasza wyjątek. Następnie usuń zadanie zthis.tasks. Metoda niczego nie zwraca. - W pliku
src/tasks/tasks.module.tszaimportujTasksServicez./tasks.service, a następnie dodaj do modułu listęprovidersobokcontrollersi umieść w niejTasksService. Nest tworzy tylko te klasy, które moduł wymienia na tej liście. - W pliku
src/tasks/tasks.controller.tszastąp komentarz wewnątrz klasyTasksControllerkonstruktorem z jednym parametrem zapisanym jakoprivate readonly tasksService: TasksService. Nest rozpoznaje typTasksServicei przekazuje instancję usługi. Słowaprivate readonlyprzed parametrem tworzą również polethis.tasksService, które przechowuje przekazaną wartość. To właśnie tej nazwy używają już poniższe metody.
Wypróbuj: wyślij POST z treścią { "title": "Buy milk" } na adres /tasks. Otrzymasz kod 201 i:
{ "id": 4, "title": "Buy milk", "done": false }Wyślij GET /tasks: otrzymasz cztery zadania, z Buy milk na końcu. Wyślij DELETE /tasks/4: otrzymasz kod 204. Wyślij DELETE /tasks/99: otrzymasz kod 404 z "message": "Task 99 not found".
Spróbuj swoich sił
import { NotFoundException } from '@nestjs/common';
export interface Task {
id: number;
title: string;
done: boolean;
createdAt?: string;
}
// Przekształć tę klasę w dostawcę, którego Nest może wstrzykiwać.
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;
}
// Zaimplementuj tutaj create(title) i remove(id).
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji TypeScript i NestJS
Poćwicz samodzielnie: Edytor online Express