V rámci vývoje v Angularu je kladeno velké důraz na práci s observables (pozorovatelnými toky), které jsou základem pro asynchronní operace. Důležitým aspektem je správné řízení předplatného těchto toků, aby se předešlo problémům s úniky paměti, což je častý problém při nesprávném ukončování observables. V této kapitole se zaměříme na dvě základní strategie, jak efektivně spravovat předplatné a zajistit, že se observables správně uzavřou.

Jednou z nejběžnějších metod je použití operátoru first(), který se často aplikuje v situacích, kdy chceme získat pouze jeden výsledek z observable toku. Tento přístup je užitečný v případě, že víme, že data, která potřebujeme, jsou okamžitá a nebudeme muset obnovovat pozorovatelný tok. Příkladem takového použití může být získání aktuálního počasí, kde požadujeme data pouze jednou na základě určitého vyhledávacího textu.

typescript
updateCurrentWeather(searchText: string, country?: string): void {
this.getCurrentWeather(searchText, country) .pipe(first()) .subscribe((weather) => this.currentWeather$.next(weather)); }

V tomto příkladu metoda getCurrentWeather vrací observable, který po zavolání metody first() automaticky zavře tok po získání prvního výsledku. Tento způsob je ideální pro scénáře, kde nechceme, aby aplikace zůstávala připojena k observable toku déle než je nutné. Jakmile je komponenta odstraněna nebo zničena, observable se automaticky uzavře, což zabraňuje únikům paměti.

Druhou populární technikou je použití operátoru takeUntilDestroyed(), což je výhodné v případech, kdy komponenta potřebuje stále přijímat aktualizace, dokud není zničena. Tento přístup se hodí pro situace, kdy komponenta bude aktualizována na základě interakce uživatele, například při změně vyhledávacího textu.

typescript
ngOnInit(): void {
this.weatherService .getCurrentWeather('Bethesda', 'US') .pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((data) => (this.current = data));
}

Operátor takeUntilDestroyed je součástí balíčku RxJS Interop a umožňuje, aby observable tok byl automaticky ukončen při zničení komponenty. Tento přístup je zvláště užitečný v případech, kdy komponenta potřebuje dynamicky reagovat na změny stavu, ale chceme se vyhnout manuálnímu řízení životního cyklu předplatného, což by mohlo vést k chybám nebo únikům paměti.

Další důležitou zásadou je, že předplatné by mělo být co nejvíce "implicitní" a mělo by využívat nástroje, které Angular nabízí pro práci s asynchronními daty. Místo používání metody subscribe() přímo v komponentě je lepší využívat async pipe v šablonách, což umožňuje Angularu automaticky řídit životní cyklus předplatného.

typescript
export class CurrentWeatherComponent { current$: Observable<ICurrentWeather>; constructor(private weatherService: WeatherService) {
this.current$ = this.weatherService.currentWeather$;
} }

V šabloně pak jednoduše použijeme:

html
<div *ngIf="current$ | async as current"> {{ current }} </div>

Tato metoda je nejen čistší, ale také efektivní, protože async pipe automaticky spravuje předplatné a jeho odhlášení, což výrazně zjednodušuje práci s asynchronními daty. Tato technika také přispívá k lepšímu udržování kódu, protože odstraní potřebu explicitního řízení životního cyklu předplatného v komponentě.

Pokud se podíváme na příklad komponenty, která využívá valueChanges z FormControl, můžeme vidět, jak efektivně spravovat asynchronní tok hodnoty vyhledávání bez přepínání mezi paradigmaty:

typescript
this.search.valueChanges .pipe( takeUntilDestroyed(),
filter(() => this.search.valid),
debounceTime(1000), tap((searchValue: string) => this.doSearch(searchValue)) ) .subscribe();

Tento příklad ukazuje, jak se vyhnout problémům s imperativním stylem kódu, kdy byste museli pracovat s callback funkcemi uvnitř subscribe(). Místo toho používáme reaktivní operátory jako filter, debounceTime, a tap, což umožňuje čisté a přehledné řízení toku dat.

Reaktivní programování má mnoho výhod, pokud jde o efektivní správu asynchronního chování v aplikacích. Angular, jako framework postavený na asynchronní architektuře, poskytuje nástroje, které vám umožní zůstat v reaktivním paradigmatě a neuchýlit se k imperativnímu způsobu programování. To nejen že zjednodušuje kód, ale také zajišťuje jeho lepší údržbu a optimalizaci výkonu, zejména v komplexních aplikacích, kde je potřeba spravovat mnoho asynchronních operací.

Pokud jde o implementaci reaktivního programování, je důležité si uvědomit, že příliš časté přepínání mezi imperativním a reaktivním stylem může vést k nečekaným vedlejším účinkům a chybám v kódu. Měli bychom se vždy snažit o udržení konzistence v použití jednoho paradigmatického přístupu, aby se minimalizovala složitost a riziko chyb.

Jak nastavit GraphQL server pomocí Apollo a Express.js

Vytvoření robustní aplikace s GraphQL a Express.js může být složitý, ale efektivní proces. Použití Apollo GraphQL jako součásti tohoto stacku zjednodušuje implementaci a poskytuje širokou škálu nástrojů, které umožňují snadnou práci s daty jak na straně serveru, tak na straně klienta. Apollo GraphQL je nejenom server, ale i klient, který poskytuje bohaté funkce pro správu dat a vývojářské nástroje. Tento nástroj je oblíbený mezi vývojáři díky své modularitě a přívětivosti pro vývojáře, což ho činí ideálním pro všechny úrovně zkušeností.

Apollo Client a Apollo Server jsou dvě klíčové komponenty, které tvoří základ tohoto nástroje. Apollo Client je GraphQL klient, který usnadňuje správu dat na straně klienta, a to jak lokálně, tak i vzdáleně. Poskytuje funkce jako caching, optimistické UI aktualizace a real-time subscription. Tento klient se bez problémů integruje s většinou JavaScriptových frameworků, jako jsou React, Vue nebo Angular. Apollo Server na druhé straně je open-source GraphQL server, který spolupracuje s jakýmkoliv GraphQL schématem a poskytuje možnosti pro sledování výkonu, sledování chyb a podporu pro spojování více GraphQL API do jednoho sjednoceného API.

Pro zajištění komplexní funkčnosti aplikace je rovněž k dispozici Apollo Studio, které poskytuje rozšířené nástroje pro vývojáře a usnadňuje práci s různými verzemi API. Apollo Federation, součást tohoto nástroje, umožňuje rozdělení monolitických GraphQL API do menších mikroservisů, což usnadňuje jejich správu a údržbu. Apollo Link je dalším nástrojem, který vývojářům umožňuje vytvářet řetězy "linků" pro správu úkolů jako je logging, retry požadavků nebo offline caching.

Vytvoření serveru s Apollo a Express.js je přímý proces. Po instalaci Apollo serveru je potřeba načíst schéma a resolvery, které definují strukturu a logiku API. Express.js, známý pro svou jednoduchost a flexibilitu, se používá k nastavení serveru a směrování požadavků na odpovídající API endpointy. Pro správu celého procesu je potřeba nakonfigurovat aplikaci a server tak, aby obsluhoval jak REST, tak GraphQL API, což umožňuje vysoce flexibilní a škálovatelný backend. Příkladem může být konfigurace souboru index.ts, kde se pomocí useGraphQL funkce startuje Apollo server na portu definovaném v konfiguračním souboru.

V rámci struktury backendu je kladeno důraz na jasné oddělení vrstev. Aplikace se skládá z několika klíčových komponent:

  1. Config.ts - Tento soubor spravuje environmentální proměnné a nastavení aplikace.

  2. App.ts - Tento soubor slouží k definici hlavní konfigurace Express.js a směrování API cest.

  3. GraphQL (api.graphql.ts) - Obsahuje definici GraphQL schématu a resolvery, které implementují požadavky na data.

  4. Services - Aplikační logika je uložena v servisních souborech, které interagují s databází.

  5. Models - Modely, jako je user.ts, se používají pro práci s databázemi.

V tomto kontextu je důležité pochopit, že pro správnou integraci GraphQL API s Express.js je nutné zajistit, aby GraphQL server byl správně konfigurován a spojen s resolvery a schématy. Schéma v GraphQL je tím, co definuje dostupná data a operace, které mohou být provedeny na serveru, a je neoddělitelnou součástí celkového návrhu.

V souvislosti s tím, jak nastavit správnou strukturu pro GraphQL a Express.js, je také nezbytné věnovat pozornost výběru správného nástroje pro vývoj a testování. Například GraphQL Playground nebo Apollo Studio poskytují interaktivní prostředí, které usnadňuje testování a ladění API. Využití těchto nástrojů může výrazně zlepšit efektivitu vývoje, zejména pokud jde o vývoj a testování komplexních API.

Co je tedy důležité pro čtenáře, který se zaměřuje na integraci GraphQL do svého projektu pomocí Apollo a Express.js? Nejdůležitější je mít jasně definované schéma a správně nakonfigurovaný server. Další krok je související s tím, jak správně a efektivně využívat nástroje jako Apollo Client pro správu dat na straně klienta a Apollo Server pro zajištění bezchybného fungování API na straně serveru. Důraz by měl být kladen na pochopení, jak jednotlivé části serveru spolupracují, a jakým způsobem optimalizovat vývojářskou zkušenost pomocí dostupných nástrojů a metodik. Samotná implementace může být složitá, ale s dobrým porozuměním architektuře a dostupným nástrojům se stává mnohem jednodušší a efektivnější.