Menu
CoddyTech

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.

challenge icon

Wyzwanie

Łatwy

Ten 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.

  1. W src/tasks/tasks.service.ts oznacz klasę TasksService dekoratorem @Injectable() z pakietu @nestjs/common. Dzięki temu Nest może ją utworzyć i przekazywać dalej.
  2. W tej samej klasie napisz metodę create(title). Tworzy ona zadanie z kolejnym wolnym identyfikatorem (o jeden większym od największego identyfikatora w this.tasks), podanym tytułem i wartością done: false. Dodaje zadanie do this.tasks i je zwraca. Kontroler wywołuje ją dla POST /tasks, przekazując tytuł z treści żądania.
  3. Napisz metodę remove(id), w której id jest liczbą. Jeśli nie ma zadania o takim identyfikatorze, metoda musi zwrócić 404, tak jak findOne: najpierw wywołaj this.findOne(id), która zgłasza wyjątek. Następnie usuń zadanie z this.tasks. Metoda niczego nie zwraca.
  4. W pliku src/tasks/tasks.module.ts zaimportuj TasksService z ./tasks.service, a następnie dodaj do modułu listę providers obok controllers i umieść w niej TasksService. Nest tworzy tylko te klasy, które moduł wymienia na tej liście.
  5. W pliku src/tasks/tasks.controller.ts zastąp komentarz wewnątrz klasy TasksController konstruktorem z jednym parametrem zapisanym jako private readonly tasksService: TasksService. Nest rozpoznaje typ TasksService i przekazuje instancję usługi. Słowa private readonly przed parametrem tworzą również pole this.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).
}
quiz iconSprawdź się

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