Když dotazy GraphQL nezpomalíte, server padne v nejhorší chvíli

Z Mazovia

Valenda s úložným prostorem řeší dva problémy najednou: kde spát a kam dát věci. Jenže nabídka je široká a rozdíly mezi kusy jsou velké. Rozhoduje konstrukce, materiál úložné části a to, jak se s postelí dennodenně manipuluje. Teprve tyto tři věci určují, jestli vydrží roky, nebo se rozpadne během pár měsíců.

U dívky na prahu školního věku se vyplatí volit pohovku, která se dá rozložit na lůžko pro návštěvu, ale v běžném dni slouží k sezení a čtení. Kompaktní dvousedadlo s hloubkou kolem osmdesáti centimetrů zabere méně místa než rozkládací trojka a přitom nabídne dost pohodlí. Pokud je dcera drobnější, nevadí ani nižší sedák; důležitější je pevný rám a sedák, který se nepropadá. Vyhněte se příliš měkkým pěnovým výplním, které po roce ztratí tvar.

Praktický kompromis představuje dvoulůžko s oddělitelnými matracemi nebo dvě úzké postele přisunuté k sobě bez mezery. Přes den vypadají jako jedna velká plocha, v noci se dají oddělit. Pozor ale na výšku matrací – pokud mají různé rozměry, vznikne mezi nimi schod, který je nepohodlný a matrace se posouvají. Vždy kupujte dvě stejné matrace ze stejné série, i když je budete používat zvlášť.

Před koupí si matraci vždy vyzkoušejte – lehněte si na ni na pět až deset minut v poloze, ve které obvykle usínáte. V prodejně si vezměte na pomoc prodavače, ať zkontroluje, zda se páteř neprohýbá. Pokud kupujete přes internet, trvejte na možnosti vrácení do 14 dnů a matraci nechte rozbalit alespoň dva dny před spaním, aby si sedla.

GraphQL dává klientovi svobodu vyžádat si přesně ta pole, která potřebuje. Tahle svoboda je zároveň největší past. Každý dotaz prochází resolverovým stromem a pokud na jednom místě sáhnete do databáze nebo na vzdálené API, náklady rostou násobeně. V roce 2026 už nestačí mít funkční endpoint. Musíte vědět, kolik práce jeden dotaz skutečně vykoná, ještě než ho pustíte na produkci.

Optimalizace není jednorázový úkol. Zaveďte sledování pomalých dotazů, logujte je i s jejich složitostí a pravidelně se k nim vracejte. Co bylo rychlé loni, nemusí být rychlé za rok, až se data rozrostou. Rozumný limit, dávkování, persistence a kešování dohromady znamenají, že GraphQL zůstane rychlý i ve chvíli, kdy na něj přijde nejvíc požadavků.

Základem je měření nákladů na úrovni dotazu, ne až na úrovni celého serveru. Zaveďte výpočet složitosti ještě před samotným provedením. Každému poli přiřaďte váhu podle toho, co obsluha resolveru reálně dělá, a násobte ji podle hloubky a počtu opakování. Dotaz, který překročí rozumný limit, odmítněte ještě před tím, než se dostane k databázi. Tím zabráníte tomu, aby jeden nešťastný klient položil celou službu.

Nezapomínejte ani na kešování na úrovni odpovědí. Pokud se stejný dotaz se stejnými parametry opakuje, není důvod ho počítat znovu. Krátká keš s rozumnou invalidací odstraní většinu špičkového zatížení. Naopak sledujte, co kešujete: osobní data a výsledky závislé na přihlášeném uživateli se kešovat nesmí, jinak si vyrobíte únik dat. Každé pole by mělo mít jasně dané, jestli je veřejné, nebo vázané na kontext.

Základní pravidlo, které se vyplatí dodržet: buď pohovka splývá se stěnou, nebo se od ní záměrně odlišuje. Half-way řešení, kdy je rozdíl jen nepatrný, působí jako chyba v nátěru. Pokud chcete klidný, vzdušný dojem, zvolte pohovku o jeden až dva stupně tmavší nebo světlejší než stěna ve stejném barevném podtónu. Když chcete kontrast, musí být čitelný — béžová pohovka u krémové stěny kontrast nevytvoří, jen vznikne šedavý nádech.

Problém N+1 se nevyřeší sám. Resolvery, které pro každou položku seznamu volají databázi zvlášť, jsou nejběžnější příčinou pomalých dotazů. Řešením je dávkování a kešování v rámci jednoho požadavku. Načtěte všechny potřebné identifikátory najednou, seskupte je a teprve pak se ptejte databáze. V praxi to znamená použít nástroj pro dávkování, který sbírá požadavky v jednom taktu smyčky událostí a odešle je jako jeden dotaz.

Hloubka, aliasy a pole, která nikdo nečekal Nejčastější chyba je ignorování hloubky dotazu. Klient může zanořit spojení do sebe sama a vytvořit tak rekurzivní strukturu, která vypadá nevině, ale vygeneruje tisíce dotazů do databáze. Nastavte maximální hloubku a tvrdě ji vynucujte. Stejný problém způsobují aliasy: jeden klient pošle stejné pole dvacetkrát pod různými jmény a obejde tak všechny limity. Počítejte s aliasy při výpočtu složitosti a omezujte jejich počet.

Persistence dotazů je další vrstva ochrany. Místo abyste posílali celý text dotazu, pošlete jeho hash a server si dotaz vyzvedne z předem schváleného seznamu. Tím zmizí riziko, že někdo pošle upravený, dražší dotaz, a zároveň se zmenší přenosová zátěž. Pro veřejná rozhraní je to dnes prakticky nutnost. U interních klientů to zvažte podle toho, jak často se dotazy mění.