
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.
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().
Powiązane case studies


Marketplace premium kosmetyków na 9 rynkach europejskich - Shopify Plus
Klient: Baza Cosmetics

Platforma edukacyjna generująca materiały do nauki programowania z ChatGPT
Klient: Klient (Aplikacja webowa do nauki programowania)
Branża: Edukacja / EdTech
Łą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
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.
Turso - nowoczesna baza danych oparta na SQLite. Co warto o niej wiedzieć?
Turso to baza danych oparta na SQLite, która pozwala dać każdemu klientowi osobną bazę, pracować offline z późniejszą synchronizacją i wyszukiwać dane po znaczeniu. Na przykładzie jednej aplikacji pokazujemy, co Turso daje na kolejnych etapach rozwoju produktu i kiedy lepiej wybrać coś innego.
DuckDB - dlaczego analityczna baza danych działa bez serwera
DuckDB to analityczna baza danych, która działa wewnątrz aplikacji, bez serwera i bez administratora. Wyjaśniamy, skąd bierze się jej szybkość, jak czyta pliki CSV i Parquet bez importu, gdzie sprawdza się w firmie, czego nie zastąpi i co zmienia zapowiadany tryb serwera w wersji 2.0.
Bruno - open source’owa alternatywa dla Postmana. Kiedy zmiana narzędzia ma sens?
Od marca 2026 r. darmowy Postman obsługuje tylko jednego użytkownika, a kolekcje zapytań do API wciąż są głównie w chmurze dostawcy. Wyjaśniamy, czym jest Bruno, ile kosztuje przejście i w jakich zespołach nie ma ono sensu.
ElectricSQL - synchronizacja danych w czasie rzeczywistym. Jak działa i do czego służy?
ElectricSQL przesyła zmiany z bazy PostgreSQL prosto na ekrany użytkowników, bez ręcznego odświeżania i bez budowania własnej warstwy powiadomień. Tłumaczymy, jak działa ten silnik synchronizacji, jakie ma ograniczenia i w jakich projektach lepiej wybrać coś prostszego.
Hono - szybka i lekka alternatywa dla Express.js
Express.js od 2010 r. jest domyślnym wyborem do budowy API w JavaScripcie. Hono robi to samo, ale działa też poza Node.js, nie ma żadnych zależności i jest wielokrotnie mniejsze. Sprawdzamy, gdzie ta różnica ma znaczenie, a gdzie lepiej zostać przy Expressie.





