Poslední novinky

Výhody a nevýhody GraphQL

Po měsíci práce jako GraphQL vývojář jsem nabyl dojmu, že už vím úplně všechno a že můžu poučovat ostatní. V tomto článku Vám zkusím předat takový první insight do této technologie pohledem programátora, který ještě před měsícem nevěděl o GraphQL skoro nic. Řekneme si o čem to je a přitom se nevyhneme porovnávání s klasickým starým dobrým REST. A samozřejmě neopomenu i některé podpultové dark-side vlastnosti, které si v oslavných článcích a chvalozpěvech nepřečtete.

Co je GraphQL?

Tu nejdůležitější otázku „být či nebýt“ Vám zodpovím někdy jindy, dneska si pojďme říct, co to vlastně GraphQL je. GraphQL je v první řadě hlavně koncept. Jasně, na graphql.org je trochu delší a komplexnější verze, ale představte si to v první řadě jen jako koncept. GraphQL totiž není vázáno na žádnou konkrétní implementaci, technologii či produkt. Je to vlastně velmi obecný předpis, jak spolu služby komunikují a předávají si data. A jak už znávu QL (query language) vyplývá, hlavní změna se odehrává v tom, jak si o data říkáme.

Proč je GraphQL?

GraphQL má ambice stát se náhradou za REST. Pro úplné zelenáče, REST jsou taková ta volání jako

HTTP GET http://www.appdomain.com/users/123/address

kdy se url adresa mění podle toho, co potřebujete udělat, stejně tak se mění i použitá metoda, tedy např GET pro čtení, POST pro vytvoření atd.

GraphQL v tomto směru přichází se zcela zásadní myšlenkou, která práci s API výrazně zjednodušuje. Tedy myšlenka jednoho jediného endpointu, který se nemění. Mění se jen data, která na něj posíláme, podle toho, co zrovna chceme udělat. Díky tomu nám odpadávají všechny ty komplikované URL konstrukce a střídání HTTP metod.

Další motivací je kontrolovat (a snížit) traffic mezi clientem (za clienta považujme frontendovou aplikaci) a Vaším API. V GraphQL je totiž třeba přesně specifikovat, která data chcete vydolovat a ta se i vrátí. Nic víc. Při volání REST API se nic takové neděje, to vrací většinou v odpovědi kompletní sadu, ze které si až client vybere, která data vlastně potřebuje. A je pravdou, že jich často bývá zlomek z toho, co dostane.

A doopravdy?

Pojďme se projít základní kameny GraphQL a podívat se na to i z té druhé stránky.

Jediný endpoint

Je skvělá věc z pohledu frontendu. To že v aplikaci komunikující s Vaším GraphQL API neni potřeba řešit žádné skládání URL adres a metod je prostě pecka. Z pohledu backendu ale brzo narazíte na problémy. Když máte totiž jediný endpoint, který vrací vše, cachování se stává noční můrou. Ne že by to nešlo, ale jde to blbě a celkem jistě se Vám to promítne na vytíženosti Vašich služeb, ze kterých GraphQL bere data, ať už jsou to databáze nebo další API. Samotné GraphQL naškálujete snadno, ale škálování staré databáze by mohl být oříšek.

Specifikace dat, které chcete

Myšlenka jasná a dobrá. Ale zas tak růžové to není. Tím že si řeknete co Vás v odpovědi zajímá a dostanete jenom to, zní moc pěkně. Časem ale přijdete na to, že specifikace dat které chcete (tzv Query) se může rozrůst do velmi komplexních a dlouhých dotazů, které v extrémních případech mohou zabírat i jednotky kilobajtů. Ale pozor, v tomto případě mluvíme o UPLOADU, tedy o datech které jdou od clienta k Vám a ten bývá značně pomalejší než DOWNLOAD. Tedy je to trochu sporné a záleží na konkrétní situaci, jestli nakonec k nějakému ušetření dat opravdu dojde. Naštěstí existuje technika nazvaná persistent query. Díky tomu na úkor nárustu počtu requestů můžete zase dostat protečená data pod kontrolu. Před každým dotazem se totiž z clienta pošle dotaz obsahující unikátní hash označující query a ta se potom pokusí najít a doplnit na úrovni GraphQL z nějakého předchozího volání, aby ji clienti nemuseli porád dokola posílat. Pokud tam ale není, musí ji následně opravdu poslat. Tedy pokud se Vám query hodně mění, moc si nepomůžete.

Tento koncept s sebou přináší další potenciální problém. Clienta vlastně vůbec nezajímá, co GraphQL musí udělat, aby dostal chtěná data. Ono je to vlastně tak trochu správně, ale bohužel se to opět podepíše na zatížení backendových služeb, ze kterých GraphQL data čerpá. Z pohledu clienta se může jednat jen o další jeden atribut, který potřebuje získat, ale pro Váš GraphQL server to může znamenat volání a párování dat z několika zdrojů. Některé query tak běžně vyústí v desítky volání, které musí GraphQL udělat, aby potřebná data vydoloval, nehledě na nepříjemnou logiku, kterou budete muset naprogramovat, aby se vše správně pospojovalo. Jasně, někde se to udělat musí, v případě REST API by si to musel vyřešit sám client. Určitě souhlasím s tím, že GraphQL je vhodnější místo, kam takovou logiku nacpat a clienta s tim neotravovat. Na co jsem chtěl ale poukázat je to, že clientskou aplikaci a její vývojáře pak vlastně nezajímá (a často ani neznají) náročnost jednotlivých operací a výpočtů a tedy nemají žádný tah na to aplikaci jakkoliv optimalizovat, to se Vám opět promítne na zatížení Vašich zdrojů.

Závěrem

GraphQL je určitě zajímavá alternativa a dost možná časem opravdu nahradí REST, nicméně vše není tak růžové, jak si přečtete v dokumentaci a uslyšíte na přednáškách. Je potřeba důkladně zvážit všechna pro i proti.