Välj rätt API-stil. Beslutsguide för REST, GraphQL, gRPC och tRPC.
Frågan jag oftast får är fel ställd: "vilket API ska vi bygga, REST eller GraphQL?". Det är som att fråga om man ska bygga en lastbil eller en sportbil utan att säga vad som ska transporteras. REST, GraphQL, gRPC och tRPC är inte fyra konkurrenter på samma bana - de är fyra svar på fyra olika frågor om vem som konsumerar API:et och hur. Den här guiden går igenom skillnaderna ärligt och säger rakt ut när mitt förstahandsval inte är rätt för er.
Jag har byggt och förvaltat alla fyra stilarna hos svenska bolag, ofta sida vid sida i samma system. Det vanliga är inte att en stil vinner, utan att olika delar av plattformen behöver olika stilar. Det här arbetet gör jag inom systemintegration.
REST: standarden av en anledning
REST över HTTP är fortfarande grundvalutan. Det är inte spännande, och det är just därför det är starkt: varje utvecklare, varje verktyg, varje proxy och varje brandvägg förstår det. Cachning fungerar via vanliga HTTP-headers, felsökning sker med curl, och en ny teammedlem är produktiv på en eftermiddag. För ett publikt API som externa parter ska integrera mot är REST nästan alltid rätt - inte för att det är tekniskt överlägset, utan för att tröskeln är lägst.
Svagheterna märks när klienterna blir mångskiftande. En mobilapp vill ha lite data, en webbvy vill ha mycket, och med fasta endpoints hamnar du i antingen overfetching (för mycket data per anrop) eller underfetching (för många anrop). Då lappar man med versioner och specialendpoints, och kontraktet börjar spreta. Det är precis där GraphQL föddes.
GraphQL: när klienten ska styra formen
GraphQL låter klienten fråga efter exakt de fält den behöver, varken mer eller mindre, från en enda endpoint. För produkter med många olika vyer och frontend-team som itererar snabbt är det en verklig produktivitetsvinst - frontend slutar vänta på att backend ska bygga en ny endpoint för varje skärm.
Men GraphQL flyttar komplexitet, det tar inte bort den. Cachning blir svårare eftersom allt går via en POST till samma URL. Du måste aktivt skydda dig mot dyra, djupt nästlade frågor med query depth limiting och kostnadsanalys. Och det klassiska N+1-problemet, där en fråga utlöser hundra databasanrop, är något du löser med dataloaders - inte något ramverket löser åt dig gratis. Min ärliga hållning: välj GraphQL när klientmångfalden är ett faktiskt problem, inte för att det står på en arkitekturritning. För ett litet API med en enda konsument är GraphQL overhead utan motvärde.
gRPC: maskin till maskin, när varje millisekund räknas
gRPC bygger på HTTP/2 och Protocol Buffers - ett binärt, schemastyrt format. Det ger låg latens, kompakt payload och tvåvägs-strömning, vilket gör det till ett utmärkt val för intern kommunikation mellan tjänster i ett microservice-landskap. Schemat i .proto-filen blir ett hårt kontrakt och genererar typsäkra klienter och servrar på flera språk.
Priset är att gRPC är obekvämt i webbläsaren. Det kräver gRPC-Web och en proxy, och du kan inte felsöka med vanliga HTTP-verktyg lika enkelt. Jag rekommenderar gRPC för tjänst-till-tjänst där prestanda och strikta kontrakt väger tungt, och avråder från det som publikt API mot okända konsumenter. Där blir REST nästan alltid en mindre kostsam väg, även om gRPC vore snabbare på pappret.
tRPC: när hela stacken är TypeScript
tRPC är specialfallet som förtjänar en egen plats. Om både frontend och backend är TypeScript i samma monorepo ger tRPC end-to-end-typsäkerhet utan kodgenerering och utan något separat schema - du anropar serverfunktioner som om de vore lokala, och typerna följer med. Det tar bort en hel kategori buggar och är förvånansvärt produktivt för ett internt produktteam.
Begränsningen är lika tydlig som styrkan: tRPC är inte ett kontrakt för omvärlden. I samma sekund som en extern part, en mobilapp på annat språk eller ett tredjepartssystem ska konsumera API:et tappar tRPC sin poäng. Så min rekommendation, som ofta överraskar: tRPC är fantastiskt internt men ska du nästan aldrig exponera publikt. Behöver ni både och, lägg tRPC inåt och ett REST- eller GraphQL-lager utåt.
Så väljer jag i praktiken
Jag börjar aldrig i tekniken utan i konsumenten. Är det ett publikt API för okända integratörer? REST. Är det en produkt med många vyer och egna frontend-team? GraphQL, om mångfalden är reell. Är det interna tjänster där latens och strikta kontrakt avgör? gRPC. Är det en TypeScript-monorepo med ett internt team? tRPC. De flesta mogna plattformar jag arbetat med landar i en kombination, inte ett enda val - och det är helt i sin ordning så länge varje val är medvetet och nedskrivet.
Den vanligaste dyra missen är att välja efter trend snarare än konsument, och sedan bygga om ett år senare. Ett verkligt exempel på ett sådant omtag finns i kundcase. Det här är just den typen av tidiga vägval jag hjälper till att fatta inom systemintegration.
Relaterat
- Event-driven arkitektur med Kafka vs RabbitMQ vs AWS EventBridge
- GraphQL Federation: Microservices med ett enhetligt API-lager
- OAuth 2.0 och OIDC i produktion: Säker API-autentisering steg för steg
Vill du ta det vidare?
Jag är senior IT-konsult och hjälper svenska bolag att välja och designa API:er som håller över tid - rätt stil för rätt konsument. Boka ett förutsättningslöst samtal så går vi igenom era integrationsbehov.
“Frågan är aldrig REST eller GraphQL i sig - den är vem som konsumerar API:et och hur. Allt annat följer av det svaret.”
- Simon Axelsson
Vanliga frågor
- Är GraphQL alltid bättre än REST?
- Nej. GraphQL löser overfetching och underfetching när du har många olika klienter, men det gör cachning och skydd mot dyra frågor svårare. För ett publikt API med en handfull konsumenter är REST oftast både enklare och billigare att förvalta.
- När ska vi använda gRPC istället för REST?
- När det handlar om intern kommunikation mellan tjänster där låg latens och strikta kontrakt väger tungt. För publika API:er mot okända konsumenter rekommenderar jag fortfarande REST, eftersom gRPC kräver extra lager för att fungera i webbläsare.
- Kan vi blanda flera API-stilar i samma system?
- Ja, och det är ofta rätt. Ett vanligt mönster är tRPC eller gRPC internt och REST eller GraphQL utåt. Det viktiga är att varje val är medvetet och dokumenterat så att nästa person förstår varför.
