node.js - Jaký je rozdíl mezi Interceptor, Middleware a Filter v Nest.js?
Jaký je rozdíl mezi Interceptorem, Filtrech a Middleware ve frameworku Nest.js? Kdy by měl být každý z nich použit a upřednostněn před ostatními?
Děkuji
Odpověď č. 1
Jak jste již naznačil svým dotazem, všechny tři jsou velmi podobné koncepty a v mnoha případech je těžké se rozhodnout a záleží to na vašich preferencích. Ale mohu poskytnout přehled rozdílů:
Stíhače
Interceptory mají přístup k odpovědi/žádosti před tím a po vyvolání zpracovatele trasy.
Registrace
- Přímo v třídě kontroleru s
@UseInterceptors()pro kontroler nebo metodu - Globálně s
app.useGlobalInterceptors()vmain.ts
Příklady
- LoggingInterceptor: Požadavek před zpracovatelem trasy a poté jeho výsledek. Změřte čas, který to zabere.
- ResultMapping: Přeměňte
nullna[]nebo zabalte výsledek do objektu odpovědi:users->{users: users}
Závěr
Líbí se mi, že registrace je blíže k zpracovatelům tras ve srovnání s middleware. Ale existují některá omezení, například nelze nastavit kód odpovědi ani upravit odpověď pomocí Interceptorů, když odesíláte response pomocí specifického objektu @Res() knihovny ve vašem zpracovateli trasy, viz dokumentace.
Prostřední software
Middleware se volá pouze před zavoláním zpracovatele trasy. Máte přístup k objektu odpovědi, ale nemáte výsledek zpracovatele trasy. Jsou to v podstatě funkce middleware pro Express.
Registrace
- V modulu velmi flexibilní způsob výběru relevantních cest (s použitím zástupných znaků, podle metody,...)
- Celosvětově s
app.use()vmain.ts
Příklady
- FrontendMiddleware: přesměrujte všechny cesty kromě API na
index.html, viz tento vlákno - Můžete použít jakýkoliv existující middleware pro Express. Existuje spousta knihoven, např.
body-parsernebomorgan
Závěr
Registrace middleware je velmi flexibilní, například: použít na všechny trasy kromě jedné atd. Ale protože jsou registrovány v modulu, možná si neuvědomíte, že se vztahují na váš kontroler, když se díváte na jeho metody. Je také skvělé, že můžete využít všechny knihovny middleware pro Express, které jsou k dispozici.
Filtry výjimek
Filtry výjimek jsou volány po obsluze trasy a po interceptorech. Jsou posledním místem, kde lze provádět změny, než odejde odpověď.
Registrace
- Přímo ve třídě kontroleru s
@UseFilters()omezené na kontroler nebo metodu - Globálně
app.useGlobalFilters()ve vašemmain.ts
Příklady
- UnauthorizedFilter: Převést na zprávu srozumitelnou pro uživatele
- NotFoundFilter: Namapujte všechny cesty, které nebyly nalezeny (nejsou součástí vašeho API), na váš
index.html.
Závěr
Základní použití filtrů výjimek je poskytovat srozumitelné chybové zprávy (skrývání technických detailů). Ale existují i jiné kreativní způsoby jejich použití: Když poskytujete jednorázovou webovou aplikaci, obvykle by všechny cesty měly přesměrovávat na index.html kromě cest vaší API. Zde můžete přesměrovat při NotFoundException. Někteří mohou považovat toto za chytré, jiní za podvodné. Volba je na vás. ;-)
Takže pořadí vykonávání je:
Middleware -> Interceptor -> Zpracovatel trasy -> Interceptor -> Filtr výjimek (pokud je vyhozena výjimka)
U všech tří z nich můžete do jejich konstruktoru vkládat další závislosti (jako služby,...).
Odpověď č. 2
Pro ty z nás, kteří tomu „rozumí“ lépe vizuálně, jsem vytvořil tento diagram pipeline NestJs založený na nejnovější verzi v6.10. Neváhejte prosím upozornit na případné nepřesnosti. Přezkoumám jej a v případě potřeby jej okamžitě aktualizuji.
Odpověď č. 3
Předpokládám, že máte na mysli Pipes místo Filters, protože Filters jsou primárně spojeny s ošetřováním výjimek.
Určitě existuje nějaké překrytí, protože middleware je flexibilní způsob, jak sestavit jakoukoli webovou aplikaci, ale jsou spíše obecným konceptem (vytváření zásobníku funkcí pro vytvoření pipeline). Ostatní jsou koncepty specifické pro Nest a jako takové se přirozeněji propojují s věcmi, jako je Dependency Injection.
Trubky se používají k transformaci vstupních dat (a případně k provádění ověřování).
Interceptory jsou opravdu skvělé, protože mohou transformovat data jak přicházející do vašeho API, tak odcházející z něj. Dávají vám možnost měnit to, co by původní handler vrátil, pomocí použití pozorovatelných toků. To je něco, co byste pravděpodobně museli implementovat pomocí dvou middlewarů (na obou stranách handleru).
Používejte trubky (Pipes), když chcete transformovat data přicházející do handleru.
Používejte interceptory, když je vyžadována oboustranná transformace.
Používejte middlewary, když chcete držet bližší k tradičnímu způsobu (např. Express) vytváření vaší webové aplikace, nebo když chcete širším způsobem aplikovat funkcionalitu na mnoho handlerů najednou (váš kód pak obsahuje méně dekorátorů).
