GraphQL er en teknologi det var masse snakk om da vi startet kode24, helt tilbake i 2018.
Og i 2021 er det fortsatt på vei oppover.
Selskap som Sanity har omfavnet det, og rammeverk som Gatsby tar utgangspunkt i at du vil bruke det.
Likevel er det mange som klamrer seg til REST-API-er. Underskrevne inkludert. Kanskje er det fordi vi ikke har blitt forklart grundig hva fordelene er?
27 år gamle Camilla Marie Dalan i Capra Consulting utviklet inntil nylig et prosjekt for startupen Fieldmade, som skaper en markedsplass for kjøp, salg og utvikling av nye 3D printer-deler.
Og hun digger GraphQL.
- Camilla, hvordan ville du forklart GraphQL til en fersk utvikler i 2021?
Du kjenner sikkert til REST med sine mange strukturerte endepunkter:
For å få tak i en entitet, la oss si en hundeeier, må vi sende et kall til for eksempel “/dogOwners/”.
Hvis vi i tillegg vil ha informasjon om andre entiteter som tilhører den førstnevnte, la oss si hundene til denne eieren, må vi sende enda et nytt API-kall, f.eks. “/dogOwners/dogs“.
Og sånn fortsetter det.
- Gatsby med GraphQL er genialt
Tenk deg om du skulle laget en webapp for sosialisering mellom hundeeiere, en “Facebook” for hundeeiere. Tenk deg videre at du skulle hentet ut alle hundeeierne, funnet antall andre hundeeier-venner de har, samt hvilke hunder de er eiere av, alt til én side (rent hypotetisk). Det hadde krevd endel API-kall, det. 🤔
Hva om du hadde kunnet sendt bare ett API-kall og bedt om akkurat det du trengte? Hverken mer eller mindre. Og at du får tilbake dataen i et JSON-format som er akkurat sånn på det formatet du vil ha det. “GraphQL to your rescue!”
I stedet for å bygge opp et API med mange endepunkter som er strukturert basert på konvensjoner, kan du bygge din egen sterkt typede graf, og spørre etter akkurat det du trenger fra denne grafen. Denne grafen sier hvilke entiteter du har og hvordan du kan spørre om eller endre på dataen av disse entitetene, kalt “queries” og “mutations”.
Grafen tilrettelegger altså for å lage API-er med frontend i tankene.
- Gatsby er fantastisk, bortsett fra GraphQL
- Så GraphQL egner seg altså best til..?
GraphQL egner seg spesielt godt til litt kompliserte webapplikasjoner som har mange koblinger mellom entiteter og der webappen ofte trenger å gjøre spørre om eller gjøre endringer på flere av disse entitetene sammen.
Et klassisk eksempel på dette er Facebook, som også er der GraphQL oppstod.
En annen styrke ved GraphQL er at, om man allerede har REST i form av mikrotjenester, kan den hjelpe til å “sy sammen” alt til ett API som er enkelt å konsumere på frontenden.
Videre kan GraphQL også være en god “gateway” for frontenden i det at man kan spesifisere grafen etter akkurat hva frontenden trenger. Det være om man legger GraphQL rett oppå databaselaget, eller over et annet API som REST.
«Siden man definerer en sterkt typet graf, er GraphQL selv-dokumenterende.»
Det egner seg også godt for rask prototyping av frontenden da det er veldig lett å endre på hvordan dataen ser ut uten at den underliggende dataen eller resten av backenden trenger å endre på seg.
Videre, siden man definerer en sterkt typet graf, er GraphQL selvdokumenterenede, og denne grafen fungerer som en kontrakt mellom backend og frontend som alle utviklere kan forstå.
I tillegg kan jeg skrive under på at det er veldig gøy å jobbe med!
- Hva bruker dere egentlig GraphQL til hos dere?
Hos Fieldmade bruker vi GraphQL til å sy sammen flere mirkotjenester implementert med REST.
GraphQL-laget fungerer dermed som en type gateway mellom mikrotjenestene og frontenden.
Vet du hvordan sykkelskiltene teller sykler?
- Hvilke verktøy, biblioteker og rammeverk bruker du?
Noe av det som kan være forvirrende i starten med GraphQL kan være at det er viktig å skille på GraphQL-servere og -klienter.
Når man først søker på GraphQL kommer det opp veldig mye om klientene, som Relay og Apollo Client. Da er det viktig å huske på at det er på serversiden du implementerer GraphQL API-et ditt (det er her grafen og resolversene bor), mens klientene konsumerer dette API-et.
Et verktøy for å støtte GrahpQL hos klienten, en såkalt GraphQL-klient, er strengt tatt ikke nødvendig, men gjør utviklingen mye enklere.
Et annet populært verktøy for GraphQL er GraphiQL (uttales “graphical”) som kan brukes som dokumentasjon på og til å utforske GraphQL-API-et ditt. Dette er en side som viser hvilke entiteter du har i grafen, hvilke felt du kan spørre om på disse entitetene, og hvilke metoder du kan kalle på grafen. Denne siden ser altså gjerne slik ut:
Videre finnes det mange forskjellig verktøy for å jobbe med GraphQL og det varierer veldig ut i fra hvilket språk man holder på med. Personlig syns jeg Apollo for JavaScript er et godt valg, både for server og klient. Jeg har ingen erfaring med andre klienter, som for eksempel Relay, så jeg kan ikke være skråsikker på hva som er best, men tror ikke du trår veldig feil om du starter der.
Vil man derimot implementere serveren i for eksempel Golang kan gqlgen være fint å sjekke ut.
- Hva synes du er mest tidkrevende med GraphQL?
Det kan være litt arbeid å sette seg inn i GraphQL og forstå alt av flyten og syntaks.
Etter man har satt seg inn i det tekniske er det vanskeligste å definere en god graf som går mer på API-design enn selve teknologien.
Det kan også være litt tricky å sette seg inn i caching, når man kommer seg litt videre, men når er ikke caching tricky? 🤷
Hva er greia med Gatsby?
- Er det noen språk og rammeverk som snakker ekstra godt med GraphQL?
Jeg vil slå et slag for å implementere GraphQL med TypeScript og Apollo da det har stort community og har mange hjelpemidler og verktøy som kan bistå utviklingen. Dette spesielt om du har erfaring med JavaScript/TypeScript fra før av!
- Kan du gi oss et praktisk eksempel?
La oss gå videre med eksempelet om hunder og hundeeiere for å se litt grunnleggende forskjeller mellom REST og GraphQL.
Vi tar utgangspunkt i entitetene beskrevet i boksene nedenfor “Doge” og “DogeOwner”, og har definert noen REST GET-spørringer på hver av dem.
I dette eksempelet kan GraphQL-grafen vår se slik ut:
Her har vi altså definert “Doge” og “DogeOwner” som typer, i tillegg til en type “Query”, som definerer hvilke spørringer vi tillater på grafen vår. Her ser vi for eksempel at spørringen “dogeOwner(id: ID!): DogeOwner” tar i mot en id og gir tilbake data av typen “DogeOwner”.
Men hva er det som faktisk sier hvordan vi skal få tak i dataen vi har sagt vi skal få tak i?
Jo, det gjør vi med noe som heter “resolvers”. Jeg skal ikke gå i dybden på dette her, men kort sagt så er resolvers funksjoner som implementerer hentingen av data. Dette kan være bare mockdata, kall til andre API-er, direkte interaksjon med en database, eller hva du enn kan tenke deg.
Så flyten fra klienten ser cirka slik ut:
La oss prøve den ut og spørre etter en hundeeier gjennom “dogeOwner”-spørringen:
Og du vil få tilbake denne dataen i samme format som du har spurt om den i JSON-format:
Og ikke nok med det. Hva om du har mange felt for e.g. hundeeieren, men du bare er interessert i IDen og navnet? Ja, da spør du bare om å få tilbake bare IDen og navnet.
Du kan på en måte, litt forenklet, tenke at spørringen “dogeOwner” sier hvilken entitet du ber om, og det i krøllparantes er spesifikasjonen på hvilke felter du vil ha tilbake som tilhører den entiteten.