</>
APIGuiden.se
Abstrakt datavisualisering med vågform mot mork bakgrund

Foto av Logan Voss via Unsplash

GraphQL11 min2026-03-14

GraphQL vs REST: När ska du välja vad?

En pragmatisk jämförelse av GraphQL och REST baserad på verkliga projekt. Prestanda, komplexitet, caching och organisatoriska faktorer som avgör valet.

GraphQLRESTJämförelseArkitektur

Det handlar inte om bäst — utan om rätt

Debatten GraphQL vs REST framställs ofta som ett antingen-eller. I verkligheten handlar det om att välja rätt verktyg för uppgiften. REST har tjänat oss väl i 20 år och fortsätter vara det bästa valet i många scenarier. GraphQL löser specifika problem som REST hanterar dåligt.

Jag har arbetat med båda i produktionssystem och sett organisationer göra kostsamma misstag åt båda hållen: team som tvingade in GraphQL i ett simpelt CRUD-API, och team som kämpade med REST trots komplexa, sammanflätade datamodeller.

Här är en ärlig jämförelse med konkreta riktlinjer.

När REST vinner

REST är det rätta valet oftare än GraphQL-entusiaster vill erkänna. Om ditt API har tydliga, väldefinierade resurser med förutsägbara åtkomstmönster, ger REST enklare implementation, bättre caching och lägre inträdeströskel.

HTTP-caching fungerar out-of-the-box med REST. GET-requests cachas av CDN:er, webbläsare och proxies utan konfiguration. Med GraphQL, där alla queries går via POST till en endpoint, behöver du implementera applikationsnivå-caching manuellt.

REST är också enklare att övervaka. Varje endpoint har en tydlig metod och URL, vilket gör monitoring och rate limiting per operation naturligt.

rest-caching.txt
http
// REST: Naturlig HTTP-caching
GET /api/products/abc-123
Cache-Control: public, max-age=3600
ETag: "v1-abc123-1709654321"

// Conditional request — sparar bandbredd
GET /api/products/abc-123
If-None-Match: "v1-abc123-1709654321"
// Svar: 304 Not Modified (ingen body)

// Enkel monitoring per endpoint
GET /api/products     → avg 45ms, 0.1% errors
POST /api/orders      → avg 120ms, 0.3% errors
GET /api/users/:id    → avg 30ms, 0.05% errors

När GraphQL vinner

GraphQL exceller i tre scenarier. Först: när klienten behöver flexibilitet. Mobilappar, dashboards och komplexa UI:er som kräver olika datakombinationer beroende på vy och enhet. Med REST resulterar detta i antingen over-fetching eller en explosion av specialändamåls-endpoints.

Andra: när du har en komplex datamodell med djupa relationer. En e-handelsplattform där produkter har varianter, varianter har lager per lagerplats, lagerplatser har leveranstider — GraphQL löser detta i en query istället för 4+ REST-requests.

Tredje: som API-gateway framför flera mikrotjänster. GraphQL Federation samlar flera domän-API:er till ett enhetligt schema.

dashboard-query.graphql
graphql
// GraphQL: En query istället för 4 REST-anrop
query DashboardData($userId: ID!) {
  user(id: $userId) {
    name
    avatar
    orders(last: 5) {
      id
      status
      total
      items {
        product { name, thumbnail }
        quantity
      }
      tracking {
        carrier
        estimatedDelivery
      }
    }
    recommendations(limit: 4) {
      product { name, price, rating }
      reason
    }
    paymentMethods {
      type
      lastFour
    }
  }
}

// Med REST: 4+ separata requests
// GET /api/users/123
// GET /api/users/123/orders?last=5
// GET /api/users/123/recommendations
// GET /api/users/123/payment-methods
// + N requests för order items

Prestanda och komplexitet

GraphQL har dolda komplexitetskostnader. Query-djupsanalys, kostnadsberäkning och N+1-prevention (DataLoader) är inte valfria i produktion — de är obligatoriska. Utan dem kan en enda query sänka din databas.

Persisterade queries (hash istället för query-sträng) löser säkerhetsrisken med godtyckliga queries, men kräver build-steg och deployment-koordinering.

REST har enklare operationell profil: standard HTTP-tools fungerar, caching är gratis och du vet exakt vad varje endpoint gör. Men REST skalar sämre designmässigt — med 50+ endpoints blir det svårt att hålla konsistens.

graphql/complexity.ts
typescript
// GraphQL: Obligatorisk kostnadsbegränsning
import {
  createComplexityPlugin
} from "graphql-query-complexity";

const complexityPlugin = createComplexityPlugin({
  maximumComplexity: 1000,
  estimators: [
    fieldExtensionsEstimator(),
    simpleEstimator({ defaultComplexity: 1 }),
  ],
});

// DataLoader — förhindrar N+1
import DataLoader from "dataloader";

function createLoaders() {
  return {
    userLoader: new DataLoader(
      async (ids: readonly string[]) => {
        const users = await db.users.findMany({
          where: { id: { in: [...ids] } },
        });
        return ids.map(
          (id) => users.find((u) => u.id === id)
        );
      }
    ),
  };
}

// Utan DataLoader:
// 100 orders → 100 separata user-queries
// Med DataLoader:
// 100 orders → 1 batched user-query

Beslutsmatris för ditt projekt

Välj REST om: ditt API har tydliga CRUD-operationer, du behöver maximal HTTP-caching, teamet har begränsad GraphQL-erfarenhet, eller API:et konsumeras primärt av tredjeparter.

Välj GraphQL om: klienterna behöver varierande datasubsets, datamodellen har komplexa relationer med 3+ nivåer, du bygger ett BFF (Backend For Frontend) för flera klienttyper, eller du behöver federation över mikrotjänster.

I praktiken ser jag ofta en hybrid: publika API:er exponeras via REST (enklare för externa konsumenter) medan interna API:er använder GraphQL (teamet kontrollerar både klient och server). Det är en pragmatisk approach som ger det bästa av båda världar.

Läs mer om grunderna i vår REST API-guide eller vår GraphQL-introduktion.