Back-end

Dekoratory w NestJS

Dekoratory znane w wielu językach programowania, służą do wywoływania funkcji wyższego rzędu w prosty dla developerów sposób. W Nest są one wykorzystywane do deklaracji m.in. modułów, kontrolerów czy klas.

Dawid Jażdżewski

Dawid Jażdżewski

Junior full stack developer

08 cze 2022

Dekoratory są bardzo dobrze znane w wielu językach programowania (np. Python), jednak w JavaScript są w dalszym ciągu relatywnie nowe. Są one wyrażeniami, które zwracają funkcje, a jako argumenty przyjmują target, nazwę oraz tak zwany property descriptor. Ich zadaniem jest możliwość wywoływania funkcji wyższego rzędu (ang. Higher-Order Functions) w przyjazny dla developera sposób - z wykorzystaniem znaku “@”. 

 

W Nest dekoratory są stosowane m.in. do deklaracji:

  • modułów - @Module(), 
  • kontrolerów- @Controller(),
  • klas, które mogą być wstrzykiwane (dependency injection), najczęściej serwisy - @injectable(). 

 

Nest udostępnia również zestaw przydatnych dekoratorów dla parametrów, których można używać razem z protokołem HTTP:

  • @Request(), @Req(),
  • @Response(), @Res(),
  • @Next(),
  • @Session(),
  • @Param(param?: string),
  • @Body(param?: string),
  • @Query(param?: string),
  • @Headers(param?: string),
  • @Ip(),
  • @HostParam().

 

Łączenie dekoratorów

Nic nie stoi na przeszkodzie, aby wykorzystać wiele dekoratorów naraz dla jednej funkcji. Można tego dokonać na dwa sposoby - wywołując dekoratory jeden pod drugim

@Get()
@HttpCode(HttpStatus.OK)
async findAll() {
  return await this.usersService.findAll();
}


lub za pomocą funkcji applyDecorators dostarczanej przez Nest. Ten sposób wymagał będzie stworzenia nowego dekoratora, który połączy nam wszystkie wymagane dekoratory:

const GetWithOkHttpStatus = () => applyDecorators(
  Get(),
  HttpCode(HttpStatus.OK)
) 
@GetWithOkHttpStatus()
async findAll() {
  return await this.usersService.findAll();
}

Tworzenie własnych dekoratorów

Można tego dokonać wykorzystując funkcję createParamDecorator - również dostarczanej przez Nest.

const CarDecorator = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.car;
  },
);

 

Powyższy przykład pokazuje jak w prosty sposób wyciągnąć klucz “car” z obiektu request, by następnie użyć go w metodzie obsługującej daną trasę.

@Get()
async findOne(@Car() car: Car) {
  console.log(car);
}

Podsumowanie

Dekoratory są narzędziem, które pozwala zachować utrzymywać czystość kodu na równi z jego funkcjonowaniem. Mimo tego, że nie są one zbyt popularne w języku JavaScript, Nest wykorzystuje je w każdym zakątku aplikacji w sposób łatwy i przejrzysty. 

FAQ

FAQ – Dekoratory (Decorators)

  • Dekoratory to wzorzec programistyczny opakowujący funkcje lub klasy w dodatkowe zachowanie, zapisywany składnią @dekorator nad deklaracją. Typowe zastosowania: logowanie wywołań, cache (memoizacja), autoryzacja (kontrola uprawnień przed wykonaniem), walidacja wejścia, pomiar czasu wykonania, logika ponawiania i definicje tras HTTP (Flask, FastAPI, NestJS). Natywnie wspiera je Python; TypeScript ustabilizował dekoratory w wersji 5, a adnotacje w Javie i atrybuty w C# pełnią zbliżoną rolę. Dla programisty Pythona to umiejętność obowiązkowa.

  • Mechanika i praktyka:

    • składnia — @dekorator nad funkcją to cukier na zapis funkcja = dekorator(funkcja),
    • wbudowane — @property, @staticmethod, @classmethod, @functools.lru_cache (memoizacja), @dataclass,
    • własne — funkcja przyjmująca funkcję i zwracająca wrapper, który wykonuje kod przed i po wywołaniu,
    • dekoratory z argumentami — dodatkowy poziom zagnieżdżenia: fabryka zwracająca dekorator,
    • dekoratory klas — opakowanie całej klasy.

    Żelazna zasada: functools.wraps we wrapperze, żeby zachować nazwę i docstring dekorowanej funkcji — bez tego debugowanie i introspekcja cierpią.

  • Po latach w statusie eksperymentalnym dekoratory ustabilizowały się wraz z TypeScriptem 5 (standard TC39). Odmiany: dekoratory klas, metod, właściwości i parametrów. W praktyce żyją przede wszystkim w dwóch ekosystemach: Angular (@Component, @Injectable) i NestJS (@Controller, @Get) — obsługują wstrzykiwanie zależności, routing, walidację (class-validator) i serializację (class-transformer). Dla developerów Angulara i NestJS to chleb powszedni; w pozostałych projektach TypeScript stosuje się je wybiórczo, bo dodają warstwę abstrakcji, która potrafi ukrywać zachowanie i utrudniać debugowanie.

  • Kanoniczne zastosowania:

    • logowanie — @log rejestruje każde wywołanie,
    • cache — @lru_cache przechowuje wyniki powtarzalnych wywołań,
    • autoryzacja — @login_required, @admin_only przed wykonaniem funkcji,
    • walidacja argumentów,
    • profilowanie — pomiar czasu wykonania,
    • ponawianie — @retry dla zawodnych operacji,
    • trasy HTTP — @app.route we Flasku, @app.get w FastAPI, @Get w NestJS,
    • Django — @login_required, @require_POST w widokach.

    Wspólny mianownik: sprawy przekrojowe (logowanie, bezpieczeństwo, walidacja) oddzielone od logiki biznesowej — to właśnie tu dekoratory błyszczą.

  • Zasady:

    • jedna odpowiedzialność — dekorator robi jedną rzecz; nie łącz logowania z cache i walidacją,
    • zachowanie metadanych — functools.wraps w Pythonie,
    • testowalność — dekoratory testuje się jak każdy kod: opakuj funkcję testową i sprawdź zachowanie,
    • dokumentacja — abstrakcja ukrywa działanie, więc opisz je wprost,
    • umiar w piętrzeniu — stos pięciu dekoratorów nad funkcją jest nieczytelny,
    • wydajność — wrapper to narzut; ostrożnie na gorących ścieżkach.

    Reguła nadrzędna: dekoratory do spraw przekrojowych, nigdy do logiki biznesowej — wtedy kod pozostaje modularny i przewidywalny.

Blog

Powiązane artykuły

Czytaj więcej
Back-end

GraalVM: Rewolucja w świecie wirtualnych maszyn

GraalVM wprowadza przełom w świecie wirtualnych maszyn, oferując wyjątkową uniwersalność i wydajność. Zaprojektowany z myślą o współczesnych wymaganiach programistycznych, umożliwia uruchamianie kodu napisanego w wielu językach, w tym Java, JavaScript, Python, i innych, na jednej platformie.

Tomasz Kozon
06 lut 2024
Back-end

MERN Stack – charakterystyka i zastosowanie

MERN Stack to jeden z najpopularniejszych zestawów technologii wykorzystywanych do tworzenia nowoczesnych aplikacji webowych. Dzięki połączeniu MongoDB, Express, React oraz Node.js umożliwia on budowę wydajnych i skalowalnych rozwiązań opartych w całości na języku JavaScript. Stack ten jest chętnie wybierany zarówno przez startupy, jak i doświadczone zespoły developerskie.

Tomasz Kozon
14 gru 2025
Back-end

Biome w praktyce: nowoczesne narzędzie do formatowania i lintowania kodu

Utrzymanie spójnego stylu i wysokiej jakości kodu to jedno z największych wyzwań w nowoczesnych projektach programistycznych. Wraz z rozwojem ekosystemu JavaScript i TypeScript deweloperzy coraz częściej muszą korzystać z wielu narzędzi do formatowania i lintowania, co prowadzi do złożonej konfiguracji i potencjalnych konfliktów. Biome powstało jako odpowiedź na te problemy, oferując jedno, szybkie i spójne rozwiązanie typu all-in-one.

Tomasz Kozon
04 gru 2025
Back-end

Bazel – szybkie i skalowalne budowanie projektów

Bazel to jedno z najszybszych i najbardziej niezawodnych narzędzi do budowania projektów, stworzone z myślą o pracy na dużą skalę. Dzięki inteligentnemu zarządzaniu zależnościami i zaawansowanym mechanizmom cache’owania znacząco skraca czas kompilacji, nawet w bardzo rozbudowanych repozytoriach. Pozwala zespołom pracować szybciej, stabilniej i bardziej przewidywalnie, niezależnie od stosowanych języków programowania.

Tomasz Kozon
04 gru 2025
Back-end

Czym jest PocketBase?

PocketBase to narzędzie, które w ostatnim czasie zyskuje coraz większą popularność wśród frontendowców i twórców aplikacji. Oferuje ono szybki sposób na uruchomienie kompletnego backendu bez skomplikowanej konfiguracji i integracji wielu usług. Dzięki połączeniu bazy danych, API oraz systemu autoryzacji w jednym rozwiązaniu pozwala skupić się na budowie samej aplikacji.

Tomasz Kozon
03 gru 2025
Back-end

ElysiaJS – lekki framework Node.js

ElysiaJS to jeden z najciekawszych nowych frameworków backendowych w ekosystemie JavaScript, który w krótkim czasie zyskał dużą uwagę społeczności. Łączy on lekkość, wysoką wydajność oraz podejście type-safe first, odpowiadając na realne problemy, z jakimi mierzą się współcześni twórcy API. Dzięki ścisłej integracji z Bun oraz minimalistycznej architekturze pozwala tworzyć szybkie i bezpieczne aplikacje bez nadmiaru konfiguracji.

Tomasz Kozon
01 gru 2025