Prinášame zápis z nášho workshopu zameraný na praktické použitie technológie GraphQL a naprogramovanie Android aplikácie na správu denných pripomienok.
NodeJS server
NodeJS, teda “JavaScript na serveri” je poslednými rokmi čoraz populárnejší. Vďaka svojej podobnosti s JavaScriptom v browseri je naprogramovanie GraphQL servera rýchle a jednoduché. Stačí mať nainštalovaný obyčajný textový editor, NodeJS a NPM.
Štruktúra servera vyzerá nasledovne:
Server obsahuje niekoľko hlavných častí:
- Input
- Type
- Query
- Scheme
- Resolvers
Inputs reprezentujú dáta, ktoré na server posielajú klienti. Môžu to byť dáta z frontendu, mobilnej aplikácie, atď
Types predstavujú objekty, ktoré na serveri existujú. V našom prípade je to napríklad objekt TodoItem. Okrem tohto typu to môžu byť základné skalárne typy ako Integer, String, Boolean, …
Queries umožňujú klientom získavať dáta zo servera. Hovoria o tom, ktoré dáta je možné zo servera dostať. Nič ale nehovoria o tom, akým spôsobom sa server ku dátam dostane.
Mutations umožňujú klientom upravovať dáta na serveri. Podobne ako pri queries, ani mutations nič nehovoria o tom, akým spôsobom server tieto dáta upraví.
Resolvers definujú to, akým spôsobom sa server získava alebo upravuje dáta. Sú to vlastne JavaScriptové funkcie, ktoré vykonávajú dané úlohy.
Schema (schéma) je spojenie queries, mutations a resolvers. Reprezentuje teda rozhranie servera, t.j. to, čo server dokáže klientom poskytnúť.
Na vytvorenie jednoduchého GraphQL servera v NodeJS najskôr potrebujeme vytvoriť NodeJS projekt. Jeho štruktúra môže vyzerať nasledovne.
Závislosti projektu si nadefinujeme v súbore package.json. Kedže server na svoje fungovanie potrebuje 4 NPM balíčky, obsah súboru vyzerá nasledovne.
Pomocou príkazu npm install nainštalujeme všetky potrebné závislosti a v projekte sa nám objaví priečinok node_modules, ktorý tieto závislosti obsahuje.
Teraz si do súboru schema.js zadefinujeme typy a queries, ktoré náš server obsahuje:
Teraz potrebujeme zadefinovať to, ako server pristupuje ku dátam. Urobíme to v súbore resolvers.js:
Keď máme zadefinované typy dát, queries a tiež resolvers, potrebujeme ich ešte vzájomne prepojiť a poskytnúť von vo forme HTTP servera. Túto záverečnú funkčnosť pripravíme v súbore index.js.
V skratke:
Na začiatku vytvoríme express server a uložíme ho do premennej server.
Potom prepojíme queries, types a resolvers a uložíme si ich to premennej executableSchema.
Následne túto schému použijeme na vytvorenie tzv. handlera, ktorý sa stará o komunikáciu s “vonkajším svetom”.
Na záver tohto handlera vložíme na adresu /api aby bol prístupný pre klientov.
Server spustíme na porte 4000.
Teraz stačí otvoriť vo webovom prehliadači adresu http://127.0.0.1:4000/api a zobrazí sa nám výsledný GraphQL server:
A môžeme sa začať hrať :) Zdrojové kódy servera sú dostupné na tomto linku.
Android apollo client
Vytvorenie Android aplikácie komunikujúcej so serverom si žiada nejeden komponent, pokiaľ dáme dohromady funkčnú aplikáciu. Keď to celé zjednodušíme, ide o prenos dát zo strany servera k aplikácií a naopak. Ak sa nad tým zamyslím v tomto smere, tak by takáto aplikácia mohla byť hotová za pár hodín. Či už ide o jednoduchý ToDo list, receptár, či administračný systém.
No keď si sadneme za počítač a povieme si “Tak poďme nato” začne sa objavovať veľa rutinných krokov, nad ktorými môžeme stráviť viac času ako by sme pôvodne plánovali.
Na uplynulom workshope sme si ukázali ako vytvoriť aplikáciu pomocou technológie GraphQl a zbaviť sa duplicitnej programátorskej práce na strane klienta a servera.
Ak sa rozhodneme vytvoriť aplikáciu pomocou REST klienta, tak kroky pri uložení dát môžu vyzerať nasledovne.
Pri použití GraphQl sa ponúka viacero výhod. No mňa osobne najviac zaujalo množstvo kódu a času, ktorý si môžeme ušetriť ak použijeme Apollo GraphQl klienta. Časti kódu, ktoré za nás vygeneruje, som načrtol na obrázku vyššie. V ukážke používame server NodeJs naprogramovaný v prvej časti workshopu, ktorý si môžete stiahnúť tu a kód pre Android klienta je tiež k dispozícií. V android projekte sú použité dve aktivity adaptér a taktiež Architecture Component, ktoré odporúčam si pozrieť. V tejto časti sa však budem venovať len zakomponovaniu GraphQl do projektu.
Najskôr je potrebné si naimportovať závislosti do build.gradle súboru.
Teraz, keď už máme nastavené potrebné závislosti, môžeme pripraviť apollo clienta. K jeho inicializácií využije builder, kde jediný povinný parameter, ktorý musíme nastaviť, je adresa, na ktorej je graphQl server. V našej aplikácií využívame lokálny graphQl server s ktorým komunikujeme cez emulátor. Z tohoto dôvou musíme použiť špecifickú ip adresu 10.0.2.2, ktorá odkazuje komunikáciu emulátora na localhost, teda ip adresu počítača.
Keď už máme pripraveného klienta, môžeme sa pustiť do tvorby graphQl requestu. Na to, aby sme mohli generovať volania, či už query, alebo mutácie, potrebuje si stiahnuť schému graphQl a vložiť ju na miesto, kde ju apollo klient bude registrovať.
Na predchádzajúcom obrázku je vyznačený priečinok, ktorý si musíme vytvoriť. Skladá sa zo slova graphql a názvu android balíčka nášho projektu. Môžeme si ho skopírovať napríklad z AndroidManifestu.xml. Do tohto priečinku budeme ukladať všetky query a mutácie súvisiace s graphQl a taktiež sa tu nachádza aj schéma.
Stiahnutie schémy
Na stiahnutie schémy využijeme príkaz z npm balíčka a to:
apollo-codegen introspect-schema http://localhost:4000/api--output schema.json
V tomto príkaze je potrebné zadať správnu hodnotu http adresy, na ktorej beží graphql server a už len spustíme príkaz. Výsledkom je súbor- schéma, ktorú vidíme na obr 3. Tú si skopírujeme do správneho priečinku a už nám nič nebráni začať využívať plnú silu graphQl klienta. Čo tým mám namysli ? No ako náhle vytvoríme a otestujeme query, ktoré vyhovuje naším požiadavkam, tak už nám staí len zbuildiť projekt a vygenerujú sa všetky potrebné triedy, ktoré môžeme začať používať.
Na obrázku je graphQl query, ktorú som si uložil pod názvom getTodos.graphql. Je dôležité povedať (napísať :D) že na rozdiel od testovacieho prostredia na webe je vhodné query pomenovať a začať kľúčovým slovom query, aby apollo klient vygeneroval správne súbory.
V prípade, že sme zadali všetko bezchybne a buildovací proces prebehne bez chýb, môžeme využívať vygenerované apollo volania. Pred tým ako sa pustíme do tejto časti, sa pozrieme čo vygeneroval klient za nás
V build podpriečinku si môžeme všimnúť záložku apollo, ktorá združuje jej vygenerované triedy. Do tohto kódu vôbec nezasahujeme, no je dobré o ňom vedieť. Pre každé volanie sa vytvorí samostatná trieda. V našom prípade tu máme GetTodosQuery, ktorá obsahuje Buildery pre volania, model objektu getAll atď.
Následné využitie tejto triedy je veľmi jednoduché. Presunieme sa do triedy modelu aktivity, ktorá je určená ako dátová vrstva našej android aplikácie a v nej vykonáme volanie.
Volanie realizujeme pomocou apollo klienta, do ktorého vkladáme vygenerované query. Výhodou je, že všetky triedy, buildery sa generujú dynamicky. Takže v prípade, že by do nášho vyhľadávania mal prísť parameter, napríklad limit počtu vrátených prvkov, jediná potrebná zmena je upravenie našej query v súbore getTodos.graphql, pregenerujeme projekt a môžeme využívať builder už aj s parametrom.
GraphQl je veľmi silný nástroj, ktorý som si obľúbil hlavne pri prototypovaní aplikácie, keďže vývoj s ním ide na strane klienta veľmi svižne. Tento workshop len pootvoril dvere k novým možnostiam, ktoré Apollo klient pre android ponúka. Veľkou výhodou klienta, môže byť riešenie automatického cachovania, lákať môže integrácia spolu reactiveRx, či s Kotlinom.