Det är 2020. Din Team alltmer lutar åt att bygga enkelsidiga applikationer, eller åtminstone inkludera rika komponenter i vanliga flersidiga applikationer. [GraphQL](https://graphql.org/) är [över två år gammalt](https://en.wikipedia.org/wiki/GraphQL) nu, vilket av JavaScript ekosystemstandarder kan betraktas som mogna. Vi kände oss lite äventyrliga, så vi avstod från de vanliga JSON API:erna och kastade oss rakt in i det - här är vad vi lärde oss.
Du behöver en GraphQL-server
I de flesta ramverk som används för webbutvecklingVerktygen för att bygga ett JSON API finns redan där. Du kan bygga en ruttstruktur och enkelt acceptera några GETs och POSTs och sedan mata ut ett JSON-svar. Ruby on Rails har till och med en speciell projekt setup switch som gör sig av med de vanliga HTML-renderingarna och lägger en solid grund för API:er i stället. Vad som följer är att en skicklig utvecklare som använder moderna verktyg kan piska upp en backend på bokstavligen några minuter.
Så är det inte med GraphQL. Även om det finns serverbibliotek för många språkMen om du inte gör det, får du ändå ett hastighetsstraff direkt från början - helt enkelt för att du måste ta reda på vad som är rätt för ditt ekosystem. På ett mer personligt plan är jag inte heller förtjust i att termen "server" används för att beskriva ett bibliotek som kan introduceras i ett projekt.
Det finns bara en slutpunkt
Under årens lopp har vi vant oss vid ett särskilt sätt att tänka kring API-struktur. På den mest grundläggande nivån följde vi helt enkelt REST-praxis. Det innebar att vi skapade flera ändpunkter per logisk modell i vår app. Det är en struktur som är lätt att förstå för både API-författare och konsumenter. Det producerar också välskodda metoder i backend, vilket gör resonemang om kod lika lätt som om själva API:et. Denna struktur är också lätt att namnge, t.ex. för ändamålen API-versionering.
GraphQL använder bara en enda slutpunkt, vanligtvis /graphql
. Varje begäran till ditt API kommer att anlända som en POST-begäran till den slutpunkten, och därifrån är det GraphQL-serverns ansvar att räkna ut vad klienten vill ha och svara på lämpligt sätt.
Vid första anblicken känns det krångligt: tänk dig att försöka göra allt i ett JSON API med en enda endpoint! Det börjar dock snart bli meningsfullt när ditt API mognar och vissa saker ersätts av andra. Depreciering i klassiska API:er görs vanligtvis på namnrymdsnivå och flyttas från v1
till v2
. GraphQL ger mycket mer kontroll, upp till att avregistrera ett enda fält. Tänk dig att kunna berätta för en REST API-konsument att du inte vill att de ska använda namn
fält och att använda snyggt_namn
istället! Det visar sig att det som först kändes krångligt faktiskt är en av de bästa funktionerna.
Allt är maskinskrivet
JSON har egentligen inte så mycket i form av typning. Det finns strängar, siffror, matriser och objekt. Utöver det har du ingen tur. I GraphQL däremot börjar och slutar allt med typer, eftersom till och med roten Query och Mutation är just det - typer. GraphQL DSL verkställer typkontroll på både servern och klienten, vilket förhindrar alla typer av obehagliga överraskningar.
Detta är mycket viktigt, särskilt som SPA:er i allt högre grad typkontrollerar sig själva, vare sig det är genom att använda TypeScript eller alternativ som Flow. GraphQL gör det enkelt att införa komplexa och sammansatta typer ovanpå standardvärdena och det blir snabbt en självklarhet för utvecklare på både backend och frontend.
Läs mer om detta: Testar JavaScript ... med Ruby?!
Dokumenten är inbyggda
I ett klassiskt JSON API kan dokumentationen vara en eftertanke. Och även om den inte är det finns det många metoder att välja mellan. Ska vi använda något schema som OpenAPI? Konverterar vi det sedan till mänsklig läsbar form med verktyg som Swagger? Eller ska vi bara dumpa en hel massa Markdown-filer någonstans? Även om det här problemet har lösts flera gånger kräver det fortfarande medvetna tankar och ansträngningar från teamet - först för att bygga dokumenten, sedan för att hålla dem uppdaterade och spridda. Det är ett ännu mer komplext problem när API:et har flera sektioner som bara är tillgängliga för t.ex. vissa användarroller.
I GraphQL är dokumentation en första klassens medborgare eftersom de flesta servrar tillåter dokumentation av dina typer och förfrågningar på plats. Sedan början av 2018 har GraphQL Schema Definition Language gjorts till en del av den officiella specifikationen, så det finns exakt ett sätt att dokumentera ett GraphQL API. Eftersom GraphQL gör det möjligt att definiera synligheten för vissa delar av grafen, förhindras de användare som inte borde se dokument för vad de inte kan komma åt automatiskt. Att ha tagit hand om beslutet och ha tydliga riktlinjer har varit en stor välsignelse för teamet.
Det finns bara två typer av åtgärder
I motsats till HTTP:s GET, POST, PUT, PATCH och DELETE finns det bara två typer av åtgärder i GraphQL: Frågor och mutationer. Huvudskillnaden är att Mutations kan och kommer att ändra systemets tillstånd och Queries kommer bara passivt att läsa ut data.
Jag ska erkänna att jag fortfarande är på staketet om den här. Jag tycker om HTTP:s uppsjö av verb för att interagera med resurser och kunna använda exakt rätt verktyg för jobbet. GraphQL gör det lättare att ta hand om de håriga fall där någon av HTTP-verben inte passade exakt, men medför straffet att behöva tänka på vad en viss mutation faktiskt kommer att påverka. Det kan också påpekas att eftersom det inte finns någon inbyggd standardkonvention för namngivning måste du utarbeta interna stilguider eller riskera att bygga en inkonsekvent röra.
Du behöver i stort sett en kund
Att interagera med REST API:er via HTTP är superenkelt i vaniljversionen av JavaScript, men ännu enklare med den moderna hämta
API. För GraphQL vill du däremot använda ett klientbibliotek om du vill ha riktigt bra prestanda. Det är inte omöjligt att interagera med ett GraphQL API genom att bara använda vanilj JavaScript - det är trots allt bara POST-förfrågningar. Men att bara använda långvarig webbteknik som cachelagring av begäranden för vanliga API-anrop fungerar inte eftersom POST-begäranden i allmänhet inte cachelagras.
Varje rimlig GraphQL-klient implementerar en cachemekanism för resultat på klientsidan och många fler funktioner. Tack vare alla dessa val är det en helt förbluffande uppgift att handrulla en konfiguration för en GraphQL-klient på startnivå. När du börjar med GraphQL rekommenderar jag särskilt att du tar en titt på Apollo-Boost eftersom det kommer med mycket rimliga standardvärden.
Kunden plockar ut data
Vi har alla varit där: vi drar ut en lista med data från API:et och det saknas något viktigt fält om en relaterad modell. Vi implementerar sedan ett hack som involverar N+1 förfrågningar medan vi muttrar över backend-utvecklarna som rusar runt och snabbt lägger till det. Det är vanligtvis inte fallet med ett väl implementerat GraphQL API, eftersom vi bara kan dyka in i data så djupt som vi vill. Behöver du se adressen till en kund på en order i den här batchen? Inte ett problem - åtminstone i teorin, vilket leder oss till...
Komplexitet är svårare att förutse
När man designar GraphQL från backend-sidan kan det vara svårt att tänka på alla djup som en klient kan gräva i grafen. Det finns många sätt att instrumentera och observera användningen av din graf, och efter att ha låtit dina front-end-kollegor leka ett tag kan du börja se några långa frågor som utför ganska fantasifulla läsningar av ditt datalager. I ett REST API är detta lättare att kontrollera eftersom du enkelt kan berätta omfattningen av data som kommer att nås i en enda begäran. Ofta kan denna missade komplexitet bita dig hårt när du släpper till produktion. Många av dessa gånger är det inte heller uppenbart hur man ska ta sig ur det hål man har grävt åt sig själv.
Numrerade sidor är verkligen svårt
Detta är ett grepp som är tungan-i-kinden verkligen. Du kan definitivt känna att GraphQL designades på och för Facebook genom att titta på hur den avsedda pagineringsmekanismen fungerar. De så kallade Connections är i princip oändliga strömmar av grafkanter, navigering på vilka görs genom markörer istället för de mer klassiska sidorna. Det är lätt att se hur det passar med ett oändligt flöde av inlägg i Facebook-stil, men om du vill ha en snyggt paginerad lista med möjlighet att gå till, säg, sidan 42, kommer du att få det mycket svårare. Det finns naturligtvis sätt att arbeta runt det, men det är vad de är - lösningar.
Skulle vi göra det igen?
Med alla de klagomål och skillnader som listas ovan tror du förmodligen att vi behandlar GraphQL som ett experiment som blev surt och gick direkt tillbaka till REST API: er. Det är inte sant. Om något så arbetar vi för att använda GraphQL i större utsträckning i projekt i hela organisationen. Det är en fantastisk teknik som har gjort våra jobb enklare och bättre. Vi investerade dock ursprungligen i GraphQL utan att helt inse vilken typ av växtvärk vi kommer att gå igenom.
Om du tror att GraphQL kan vara rätt för dig, uppmuntrar jag dig att ta steget. Ge dig själv gott om tid och utrymme att säkert misslyckas, så kommer du att skörda fördelarna inom kort!
Läs också:
– Hur hanterar man utvecklare på distans på ett effektivt sätt? En guide för CTO:er
– Python vs. Ruby? Vilken teknik ska du använda för produktutveckling?
– En snabbguide till hur du bygger och utvecklar din egen marknadsplats. Vad är värt att veta?