Vad är GraphQL?

Blogginlägg av Cynthia Dao

GraphQL är ett språk för API-anrop som gör det möjligt att hämta exakt den data som behövs, i ett enda anrop. Det innebär avgjort färre API-anrop än med t.ex. REST och gör det enklare för mig som utvecklare att bygga applikationer med riktigt bra prestanda. 

Headless CMS fortsätter vara ett populärt val för webbplatser och digitala tjänster. Ett headless CMS exponerar innehållet via ett API, och sedan sker presentationen av innehållet i en helt separat webbapplikation. Under flera år har REST-APIer varit ett av de absolut mest populära API-valen för headless-webbplatser. En stark utmanare de senaste åren är GraphQL, som låter mig hämta exakt den data jag behöver, vilket kan ge flera gånger bättre prestanda än med ett REST API. 

Cynthia Dao är webbutvecklare på Whitespace, med fokus på headless, JavaScript och API:er.

REST: populärt API-val som saknar precision

Med REST-API:er är det möjligt att läsa, hämta, uppdatera och radera data på en server genom en webbklient. Webbklienten gör då ett HTTP-anrop på servern som sedan svarar med status på om anropet har lyckats eller inte. När denna process sker interagerar webbklienten och servern utan att känna till varandra.

Att klienten och servern är oberoende av varandra är en av flera fördelar med ett REST-API. Det är enkelt att bygga och det kan användas av många utvecklare eftersom det är språkoberoende. Oberoendet minskar behovet av specialiserade utvecklare.  Det ger även möjlighet till cache av data för ökad prestanda. Det vill säga att första gången ett anrop görs kan svaret från servern sparas på klienten för upprepat bruk. Görs anropet flera gånger hämtas datan direkt från klienten istället för på servern.

En nackdel med REST är att det är svårt att hämta specifik data utan flera anrop till servern. För att exempelvis hämta ut en lista med titeln och brödtexten på en användares inlägg på en blogg kan det krävas flera anrop till servern. Först görs ett anrop för att hämta själva användaren. Sedan ett till anrop för att hämta inläggen och dess data. Att inte kunna hämta specifikt data utan flera anrop kan leda till ett överskott av data där du utöver titeln och texten på inläggen även får irrelevant information för ditt ändamål. Likaså kan det leda till ett underskott av data. Om anropet på inläggen enbart hade gett ut en lista på inläggens id:n, hade ett tredje anrop behövts för att hämta ut datan du vill åt. 

Under utvecklingen av en webbapplikation där många anrop görs kan detta göra REST-strukturen mer komplex. Antalet anrop påverkar också prestandan på enheterna som applikationen körs på. En långsam server behöver mer tid på sig att svara och en långsam enhet behöver mer tid att både hämta och visa ut svaret.

GraphQL: hämta bara exakt den data du behöver

Men där REST brister, briljerar GraphQL. GraphQL är ett språk som används för datahämtning via API:er. Det är skapat för att motverka den komplexitet som datahämtning med till exempel REST kan tillföra. GraphQL skapades av Lee Byron med flera på Facebook 2012 och släpptes fritt 2015. Nu drivs utvecklingen av GraphQL Foundation.

Processen för datahämtning med GraphQL är enkel och består av två delar:

  1. Ett schema där vi definierar vad för data som kan hämtas, specificerar hur datan relaterar till varandra och deklarerar med vilka funktioner datan kan anropas.
  2. Funktioner där vi indikerar vart datan ska hämtas ifrån. Här är det möjligt att hämta datan från olika databaser.

Här är ett exempel på hur vi kan gå tillväga för att hämta titeln och brödtexten på en användares inlägg med GraphQL. Först skapar vi datastrukturen för vad som ska hämtas och förtydligar hur de relaterar med varandra, i vårt exempel blir det användaren och inläggen.

type User {
 id: ID!
 name: String
 age: Int
 birthdate: Int
 posts: [Post]
}

type Post {
 id: ID!
 author: User
 title: String
 date: Int
 content: String
 path: String
 categories: [Category]
}

Därefter deklarerar vi de olika anrop som kan användas för att hämta datan. 

type Query {
 getUser(id: ID!): User
 posts: [Post]
}

Sist skapar vi funktioner där vi faktiskt hämtar och returnerar datan från valfri källa. När vi väl anropar de deklarerade funktionerna plockar vi endast ut datan vi vill ha. Datan vi får tillbaka blir en lista som innehåller namnet på användaren och relevant data på användarens inlägg.

Exempel på anrop:

query User {
 getUser(id: 91) {
  name
  posts {
   title
   content
  }
 }
}

Exempel på svar:

{
 "data": {
  "User": {
   "name": "Namn Namnsson",
   "post": [
    {
     "title": "My first post"
     "content": "Lorem ipsum dolor sit amet, consectetur adipiscing
                 elit, sed do eiusmod tempor incididunt ut labore et
                 dolore magna aliqua."
    },
    {
     "title": "My second post"
     "content": "Ut enim ad minim veniam, quis nostrud exercitation
                 ullamco laboris nisi ut aliquip ex ea commodo
                 consequat."
    }
   ]
  }
 }
}

Processen för datahämtning förenklas med GraphQL. Vi fick ut exakt den data vi ville ha – varken mer eller mindre

Nackdelar med GraphQL

Även om jag är förtjust i GraphQL så finns det några brister som är värda att tänka på.

  • GraphQL har inte stöd för cache
  • Datan som hämtas renderas bara i JSON-format.
  • GraphQL är en ganska ny teknik vilket gör att många CMS och andra applikationer fortfarande saknar stöd för GraphQL.
  • Det är svårare att hantera fel med GraphQ

Kom igång med GraphQL

Här är två bra resurser som jag ofta använder själv.