GraphQL — vad det är, frågespråk och tillämpning i mobila projekt

Författare: IT Sectr Publicerad: 2026-03-06 Lästid: 9 min

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 — frågespråk där klienten bestämmer svarets struktur
  • Löser problemen med overfetching (överflödiga data) och underfetching (brist på data)
  • Stöder query, mutation och subscription för olika typer av operationer
  • Använder en endpoint (vanligtvis /graphql) istället för flera URL:er som i REST
  • Baserat på typsystem med ett strikt schema: alla möjliga data beskrivs i förväg

Vad är GraphQL?

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.

Hur GraphQL fungerar

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:

  • Klienten skickar en POST-förfrågan till /graphql med JSON-kroppen { “query”: “...” }
  • Servern tolkar frågan, bygger ett AST (Abstract Syntax Tree) och validerar det mot schemat
  • Motorn går igenom AST, anropar resolvers för varje fält och samlar in data
  • Svaret returneras i JSON-format, exakt motsvarande frågans struktur

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.

Query, Mutation och Subscription

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:

js
// 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.

GraphQL schema och typsystem

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:

js
// 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.

Jämförelse av GraphQL med REST

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.

KriteriumRESTGraphQL
Svarets strukturFast, serverstyrdFlexibel, klientstyrd
OverfetchingOfta — servern returnerar alla fältNej — klienten begär endast nödvändiga
Antal förfrågningarFlera round-tripsEn förfrågan för all data
CachningInbyggd HTTP-cachningKräver manuell konfiguration
TypningInte inbyggd (beror på format)Strikt, via SDL-schema
Verktygcurl, Postman, SwaggerGraphiQL, Apollo Studio, Introspection
FiluppladdningInbyggt via multipartKräver ytterligare protokoll
PrestandaFörutsägbar, lättare att optimeraBeror 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.

Exempel på GraphQL-frågor

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.

Query: ladda profil med inlägg

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.

kotlin
// 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

Mutation: skapa ett nytt inlägg

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.

kotlin
// 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.

Ekosystem: Apollo, Relay och verktyg

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

Ersätter GraphQL REST?

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.

Är det svårt att migrera från REST till GraphQL?

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.

Vad är N+1-problemet i GraphQL?

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.

Hur fungerar GraphQL med filuppladdning?

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.

Är GraphQL säkert?

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

  • GraphQL — frågespråk där klienten styr svarets struktur, vilket eliminerar overfetching och underfetching
  • Tre typer av operationer: query (läsning), mutation (skrivning), subscription (realtid)
  • Använder en endpoint och ett strikt typsystem — SDL-schema
  • Till skillnad från REST löser det problemet med flera round-trips — all data i en fråga
  • Kräver DataLoader för att förhindra N+1-problemet och manuell konfiguration av cachning
  • Huvudklienter: Apollo Client (Android, iOS, Web) och Relay (React)
  • Passar bäst för komplexa gränssnitt med många relaterade entiteter och mobilapplikationer

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.

Diskutera projektet

Läs också