GraphQL — är ett frågespråk för API och en körningsmiljö för att utföra dessa frågor, utvecklat av Facebook 2012 och släppt som öppen källkod 2015. Till skillnad från REST, där servern bestämmer svarets struktur, låter GraphQL klienten exakt ange vilka data som behövs, vilket helt eliminerar problemen med overfetching och underfetching. Enligt State of JavaScript Survey (2025) använder 35% av de tillfrågade utvecklarna GraphQL, och bland stora företag har GitHub, Shopify, Airbnb och The New York Times implementerat det. GraphQL stöder tre typer av operationer: query (läsning), mutation (skrivning) och subscription (realtidsuppdateringar via WebSocket).
Huvudpunkter
GraphQL — är en specifikation och körningsmiljö för API som ger klienten fullständig kontroll över mottagna data. Utvecklad av Facebooks ingenjörer för att lösa problemen med mobilappen News Feed, publicerades specifikationen som en öppen standard 2015. Sedan 2018 förvaltas GraphQL av GraphQL Foundation med stöd av Linux Foundation och företag som Apollo, AWS, GitHub, SAP och andra.
Till skillnad från REST, där varje endpoint returnerar en fast datastruktur, använder GraphQL en enda endpoint som tar emot en frågesträng. Klienten beskriver i frågan vilka fält som behövs och servern returnerar exakt dessa. Till exempel returnerar frågan { user(id: “1”) { name email } } endast användarens name och email, utan överflödiga fält som address, phone eller createdAt som skulle behöva hämtas i REST.
GraphQL är inte bundet till någon specifik databas eller språk. Specifikationen definierar endast formatet för frågor och svar. Det finns serverimplementationer i Node.js (graphql-js, Apollo Server), Kotlin (graphql-kotlin, Netflix DGS Framework), Python (Graphene, Strawberry), Ruby (graphql-ruby) och andra språk. Klientbibliotek finns tillgängliga för alla större plattformar, inklusive Apollo Client för iOS, Android och webben.
Arkitekturen för GraphQL består av tre nyckelkomponenter: schema (Schema), resolvers (Resolvers) och exekveringsmotor (GraphQL Engine). Schemat bestämmer vilka datatyper som är tillgängliga, vilka frågor som kan utföras och vilka argument de accepterar. Resolvers är funktioner på servern som returnerar data för varje fält i schemat. Exekveringsmotorn tar emot den inkommande frågan, validerar den mot schemat, anropar lämpliga resolvers och sammanställer svaret.
Processen för att behandla en fråga ser ut så här:
Den största fördelen med GraphQL-arkitekturen är upplösning på fältnivå. I REST får utvecklaren antingen alla fält av resursen (eventuellt med överflöd) eller använder tillägg som ?fields=name,email. I GraphQL är sådan filtrering inbyggd i språket: varje fråga specificerar explicit vilka fält som behövs och servern returnerar exakt dessa. Detta är särskilt viktigt för mobilapplikationer, där mängden överförda data direkt påverkar laddningstid och dataförbrukning.
GraphQL definierar tre typer av operationer, som var och en motsvarar ett specifikt interaktionsscenario. Query — för att läsa data, analogt med GET i REST. Mutation — för att ändra data (skapa, uppdatera, ta bort), analogt med POST/PUT/DELETE. Subscription — för realtidsuppdateringar via WebSocket, vilket inte har någon direkt motsvarighet i klassisk REST (kräver ytterligare lösningar som WebSocket eller Server-Sent Events).
Grundläggande syntax för frågor är intuitiv:
// Enkel fråga med argument
query {
user(id: "42") {
name
email
avatarUrl
}
}
// Mutation med retur av ändrade data
mutation {
updateProfile(name: "Ivan") {
id
name
updatedAt
}
}
// Subscription — lyssnar efter realtidsuppdateringar
subscription {
newMessage(chatId: "chat_1") {
id
text
sender { name }
}
}
Query körs parallellt — alla fält på samma nivå laddas samtidigt. Detta gör det möjligt att ladda relaterad data (användare och dennes inlägg) med en enda fråga utan flera round-trips. Mutation körs sekventiellt — mutationer i en fråga körs en efter en i deklarationsordning. Subscription upprättar en permanent anslutning via WebSocket, genom vilken servern skickar data när en händelse inträffar.
Operationer kan acceptera variabler för att separera data från frågan, direktiv (@include, @skip) för villkorlig inkludering av fält och fragment för återanvändning av fältuppsättningar. Dessa möjligheter gör GraphQL-frågor flexibla och återanvändbara, vilket är särskilt viktigt i stora projekt med många skärmar och komponenter.
I grunden av GraphQL ligger typsystemet, som beskriver alla möjliga data och API-operationer. Schemat (Schema) är en beskrivning av de typer som servern kan returnera och de frågor som den accepterar. Schemat skrivs på språket Schema Definition Language (SDL) och fungerar som ett kontrakt mellan klienten och servern. Klienten kan hämta schemat via introspektion — en speciell fråga __schema som returnerar en fullständig beskrivning av API:et.
Exempel på schema för en blogg:
// SDL — Schema Definition Language
type User {
id: ID!
name: String!
email: String
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String
author: User!
}
type Query {
user(id: ID!): User
posts(page: Int): [Post!]!
}
Utropstecknet (!) betyder non-null fält — garanterat närvarande i svaret. Hakparenteser [ ] indikerar en lista. GraphQL stöder skalära typer (Int, Float, String, Boolean, ID), objekttyper, enum, union, interface och input-typer (för mutationsargument). Strikt typning självdokumenterar API:et och gör det möjligt för klientverktyg att generera kod: TypeScript-typer, Kotlin-dataklasser, Swift-strukturer.
Introspektion — en unik möjlighet i GraphQL som saknas i REST. Klienten kan skicka en fråga till schemat och få en fullständig beskrivning av alla typer, fält, argument och direktiv. Detta ligger till grund för verktyg som GraphiQL och Apollo Studio, som automatiskt genererar dokumentation och autokomplettering för utvecklare. Introspektion möjliggör också automatiska tester som kontrollerar schemats överensstämmelse med förväntad struktur.
Valet mellan GraphQL och REST är en av de viktigaste arkitektoniska frågorna vid design av API:er. Båda tillvägagångssätten har sina styrkor och svagheter, och valet beror på projektets specifika krav. REST vinner i enkelhet och universalitet, GraphQL i flexibilitet och frågeeffektivitet. Låt oss titta på jämförelsetabellen.
| Kriterium | REST | GraphQL |
|---|---|---|
| Svarets struktur | Fast, serverstyrd | Flexibel, klientstyrd |
| Overfetching | Ofta — servern returnerar alla fält | Nej — klienten begär endast nödvändiga |
| Antal förfrågningar | Flera round-trips | En förfrågan för all data |
| Cachning | Inbyggd HTTP-cachning | Kräver manuell konfiguration |
| Typning | Inte inbyggd (beror på format) | Strikt, via SDL-schema |
| Verktyg | curl, Postman, Swagger | GraphiQL, Apollo Studio, Introspection |
| Filuppladdning | Inbyggt via multipart | Kräver ytterligare protokoll |
| Prestanda | Förutsägbar, lättare att optimera | Beror på komplexiteten i nästlade frågor |
Den största nackdelen med GraphQL är svårigheten med cachning. I REST fungerar HTTP-cachning på URL-nivå: en förfrågan till /api/users/42 returnerar alltid samma struktur och svaret kan cachas per URL. I GraphQL går alla förfrågningar till en endpoint, svarets struktur beror på förfrågans kropp. För att lösa detta problem använder Apollo Client en normaliserad cache på klientsidan som delar upp svar i separata enheter baserat på id och automatiskt uppdaterar dem när ny data tas emot.
En annan viktig aspekt är N+1-problemet. Vid begäran av nästlad data (till exempel en användares inlägg och kommentarer till varje inlägg) kan GraphQL utföra en separat SQL-fråga för varje element i listan. Detta löses med DataLoader — ett verktyg för batchning och cachning av databasfrågor som grupperar individuella frågor i en enda batch-fråga. I REST är detta problem mindre uttalat eftersom utvecklaren kontrollerar svarets struktur på servern.
Låt oss titta på praktiska exempel på användning av GraphQL i en mobilapplikation i Kotlin med Apollo Client. Exemplen demonstrerar typiska scenarier: laddning av data för profilsidan (query), skapa ett nytt inlägg (mutation) och prenumerera på nya kommentarer (subscription). Varje exempel innehåller både GraphQL-frågan och koden på klientsidan.
En GraphQL-fråga laddar användaren, dennes senaste inlägg och totalt antal följare. I REST skulle minst 2-3 förfrågningar krävas: /users/42, /users/42/posts, /users/42/stats. GraphQL kombinerar dem i en enda round-trip, vilket minskar laddningstiden för skärmen på långsamma anslutningar.
// GraphQL-fråga (i .graphql-fil)
query ProfileScreen($userId: ID!) {
user(id: $userId) {
name
bio
avatarUrl
posts(limit: 10) {
id
title
createdAt
}
followersCount
followingCount
}
}
// Anrop på klientsidan (Apollo Client + Kotlin)
val response = apolloClient
.query(ProfileScreenQuery(userId = "42"))
.execute()
binding.nameText.text = response.data?.user?.name
Mutationen skapar inte bara resursen utan returnerar också dess aktuella data för att uppdatera UI. Fältet __typename används av Apollo Client för normalisering av cachen — klienten uppdaterar automatiskt Post-posten i cachen vid ett framgångsrikt mutationssvar.
// GraphQL-mutation
mutation CreatePost($input: CreatePostInput!) {
createPost(input: $input) {
id
title
createdAt
author {
id
name
}
}
}
// Anrop av mutation med input-typ
val input = CreatePostInput(
title = "Nytt inlägg om GraphQL",
content = "GraphQL förenklar arbetet med API:er..."
)
val result = apolloClient
.mutation(CreatePostMutation(input))
.execute()
En viktig fördel med GraphQL jämfört med REST i samband med mobil utveckling är automatisk kodgenerering. Apollo Client för Kotlin (Apollo GraphQL) genererar typsäkra klasser från .graphql-filer under byggfasen. Om servern ändrar schemat kommer projektet inte att byggas förrän frågorna har uppdaterats. Detta förhindrar körningsfel som är typiska för REST, där en förändring av svarsstrukturen kan förbli obemärkt under utvecklingen.
GraphQL-ekosystemet innehåller flera viktiga bibliotek och verktyg som förenklar utveckling och drift. Apollo Client — det mest populära klientbiblioteket, som stöder React, iOS, Android och Kotlin Multiplatform. Relay från Facebook — ett alternativ för React-applikationer med ett unikt tillvägagångssätt för datahantering och cachning. Valet mellan Apollo och Relay beror på plattform och prestandakrav.
På serversidan leder Apollo Server (Node.js), Netflix DGS Framework (Kotlin/Java) och graphql-ruby. För att utveckla schemat och testa frågor används GraphiQL — ett interaktivt IDE inbyggt i webbläsaren. Apollo Studio tillhandahåller prestandamått, frågespårning och schemahantering för produktionsmiljön. Separat bör GraphQL Code Generator nämnas — ett verktyg som genererar TypeScript-, Kotlin-, Swift- och Dart-typer från SDL-scheman.
För mobil utveckling är Apollo Kotlin (Apollo GraphQL) särskilt intressant — ett bibliotek helt skrivet i Kotlin med stöd för coroutines, Flow och Multiplatform. Det gör det möjligt att använda samma GraphQL-frågor för Android och iOS i Kotlin Multiplatform-projekt. Apollo Kotlin normaliserar cachen, stöder fel på fältnivå (partial errors) och genererar automatiskt datamodeller från .graphql-filer. Detta gör GraphQL till det föredragna valet för stora mobila projekt där utvecklingshastighet och typsäkerhet är viktiga.
Vanliga frågor
GraphQL ersätter inte REST, utan erbjuder ett alternativt tillvägagångssätt. REST är lämpligare för enkla CRUD-API:er, cachning via HTTP och offentliga API:er med förutsägbar belastning. GraphQL är optimalt för komplexa gränssnitt med många relaterade data.
Migrering är möjlig stegvis: GraphQL kan fungera som ett mellanlager (gateway) framför befintliga REST-tjänster. Många företag lägger till GraphQL vid sidan av REST utan att stänga av det gamla API:et. Fullständigt utbyte kräver omskrivning av resolvers.
N+1 uppstår när en separat databasfråga utförs för varje element i en lista. Det löses med DataLoader — ett bibliotek som batchar individuella frågor till en och cachar resultaten inom ramen för en HTTP-förfrågan.
GraphQL-specifikationen definierar inte direkt filuppladdning. I praktiken används: base64-kodning (enkelt men ineffektivt för stora filer), multipart-förfrågningar enligt protokollet graphql-multipart-request-spec eller en separat REST-endpoint för filer.
Säkerheten för GraphQL kräver ytterligare åtgärder: begränsning av nästlingsdjup, begränsning av frågekomplexitet, rate limiting på operationsnivå. Offentlig introspektion av schemat kan avslöja datastrukturen — i produktionsmiljö rekommenderas att den stängs av.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också