GraphQL — este un limbaj de interogare pentru API și un mediu de execuție pentru realizarea acestor interogări, dezvoltat de Facebook în 2012 și lansat ca open source în 2015. Spre deosebire de REST, unde serverul determină structura răspunsului, GraphQL permite clientului să indice exact ce date îi sunt necesare, eliminând complet problemele de overfetching și underfetching. Conform State of JavaScript Survey (2025), GraphQL este folosit de 35% dintre dezvoltatorii intervievați, iar printre companiile mari l-au adoptat GitHub, Shopify, Airbnb și The New York Times. GraphQL suportă trei tipuri de operații: query (citire), mutation (scriere) și subscription (actualizări în timp real prin WebSocket).
Principalele puncte
GraphQL — este o specificație și un mediu de execuție pentru API care oferă clientului control complet asupra datelor primite. Dezvoltată de inginerii Facebook pentru a rezolva problemele aplicației mobile News Feed, specificația a fost publicată ca standard deschis în 2015. Din 2018, GraphQL se află sub conducerea GraphQL Foundation cu sprijinul Linux Foundation și al companiilor precum Apollo, AWS, GitHub, SAP și altele.
Spre deosebire de REST, unde fiecare endpoint returnează o structură fixă de date, GraphQL folosește un endpoint unic care primește un șir de interogare. Clientul descrie în interogare ce câmpuri îi sunt necesare, iar serverul returnează exact acelea. De exemplu, interogarea { user(id: „1”) { name email } } va returna doar name și email ale utilizatorului, fără câmpuri suplimentare precum address, phone sau createdAt care ar trebui obținute în REST.
GraphQL nu este legat de nicio bază de date sau limbaj specific. Specificația definește doar formatul interogărilor și răspunsurilor. Există implementări de server în Node.js (graphql-js, Apollo Server), Kotlin (graphql-kotlin, Netflix DGS Framework), Python (Graphene, Strawberry), Ruby (graphql-ruby) și alte limbaje. Bibliotecile client sunt disponibile pentru toate platformele principale, inclusiv Apollo Client pentru iOS, Android și web.
Arhitectura GraphQL este formată din trei componente cheie: schema (Schema), rezolvătoarele (Resolvers) și motorul de execuție (GraphQL Engine). Schema determină ce tipuri de date sunt disponibile, ce interogări pot fi efectuate și ce argumente acceptă. Rezolvătoarele sunt funcții pe server care returnează date pentru fiecare câmp al schemei. Motorul de execuție primește interogarea de intrare, o validează față de schemă, apelează rezolvătoarele corespunzătoare și construiește răspunsul.
Procesul de procesare a interogării arată astfel:
Avantajul cheie al arhitecturii GraphQL este rezolvarea la nivel de câmp. În REST, dezvoltatorul fie primește toate câmpurile resursei (posibil cu date în plus), fie recurge la extensii precum ?fields=name,email. În GraphQL, o astfel de filtrare este încorporată în limbaj: fiecare interogare specifică explicit ce câmpuri sunt necesare, iar serverul returnează exact acelea. Acest lucru este deosebit de important pentru aplicațiile mobile, unde volumul de date transmise influențează direct viteza de încărcare și consumul de trafic.
GraphQL definește trei tipuri de operații, fiecare corespunzând unui scenariu specific de interacțiune. Query — pentru citirea datelor, analog cu GET în REST. Mutation — pentru modificarea datelor (creare, actualizare, ștergere), analog cu POST/PUT/DELETE. Subscription — pentru actualizări în timp real prin WebSocket, care nu are un echivalent direct în REST clasic (necesită soluții suplimentare precum WebSocket sau Server-Sent Events).
Sintaxa de bază a interogărilor este intuitivă:
// Interogare simplă cu argument
query {
user(id: "42") {
name
email
avatarUrl
}
}
// Mutation cu returnarea datelor modificate
mutation {
updateProfile(name: "Ion") {
id
name
updatedAt
}
}
// Subscription — ascultă actualizări în timp real
subscription {
newMessage(chatId: "chat_1") {
id
text
sender { name }
}
}
Query se execută paralel — toate câmpurile de același nivel sunt încărcate simultan. Acest lucru permite încărcarea datelor conexe (utilizatorul și postările sale) printr-o singură interogare fără round-trip-uri multiple. Mutation se execută secvențial — mutațiile dintr-o singură interogare sunt executate una după alta în ordinea declarării. Subscription stabilește o conexiune permanentă prin WebSocket, prin care serverul trimite date la producerea unui eveniment.
Operațiile pot accepta variabile pentru separarea datelor de interogare, directive (@include, @skip) pentru includerea condiționată a câmpurilor și fragmente pentru reutilizarea seturilor de câmpuri. Aceste capacități fac interogările GraphQL flexibile și reutilizabile, ceea ce este deosebit de important în proiecte mari cu numeroase ecrane și componente.
La baza GraphQL stă sistemul de tipuri, care descrie toate datele și operațiile API posibile. Schema (Schema) este o descriere a tipurilor pe care serverul le poate returna și a interogărilor pe care le acceptă. Schema este scrisă în limbajul Schema Definition Language (SDL) și servește drept contract între client și server. Clientul poate obține schema prin introspecție — o interogare specială __schema care returnează descrierea completă a API-ului.
Exemplu de schemă pentru un blog:
// 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!]!
}
Semnul exclamării (!) înseamnă câmp non-null — va fi garantat prezent în răspuns. Parantezele pătrate [ ] indică o listă. GraphQL suportă tipuri scalare (Int, Float, String, Boolean, ID), tipuri obiect, enum, union, interface și input-type (pentru argumentele mutațiilor). Tipizarea strictă auto-documentează API-ul și permite instrumentelor client să genereze cod: tipuri TypeScript, clase de date Kotlin, structuri Swift.
Introspecția — o capacitate unică a GraphQL, absentă în REST. Clientul poate trimite o interogare către schemă și poate primi descrierea completă a tuturor tipurilor, câmpurilor, argumentelor și directivelor. Aceasta stă la baza instrumentelor precum GraphiQL și Apollo Studio, care generează automat documentație și completare automată pentru dezvoltatori. Introspecția permite, de asemenea, scrierea de teste automate care verifică conformitatea schemei cu structura așteptată.
Alegerea între GraphQL și REST este una dintre întrebările arhitecturale cheie la proiectarea API-urilor. Ambele abordări au punctele lor forte și slabe, iar alegerea depinde de cerințele specifice ale proiectului. REST câștigă prin simplitate și universalitate, GraphQL — prin flexibilitate și eficiență a interogărilor. Să analizăm tabelul comparativ.
| Criteriu | REST | GraphQL |
|---|---|---|
| Structura răspunsului | Fixă, server | Flexibilă, client |
| Overfetching | Adesea — serverul returnează toate câmpurile | Nu — clientul solicită doar necesarele |
| Numărul de cereri | Round-trip-uri multiple | O singură cerere pentru toate datele |
| Cache | Cache HTTP nativ | Necesită configurare manuală |
| Tipizare | Nu este încorporată (depinde de format) | Strictă, prin schema SDL |
| Instrumente | curl, Postman, Swagger | GraphiQL, Apollo Studio, Introspection |
| Încărcare fișiere | Nativ prin multipart | Necesită protocoale suplimentare |
| Performanță | Previzibilă, mai ușor de optimizat | Depinde de complexitatea interogărilor imbricate |
Principalul dezavantaj al GraphQL este dificultatea cache-ului. În REST, cache-ul HTTP funcționează la nivel de URL: o singură cerere la /api/users/42 returnează întotdeauna aceeași structură, iar răspunsul poate fi stocat în cache după URL. În GraphQL, toate cererile merg la un singur endpoint, structura răspunsului depinzând de corpul cererii. Pentru a rezolva această problemă, Apollo Client folosește un cache normalizat pe partea clientului care împarte răspunsurile în entități separate după id și le actualizează automat la primirea de noi date.
Un alt aspect important este problema N+1. La solicitarea de date imbricate (de exemplu, postările utilizatorului și comentariile fiecărei postări), GraphQL poate executa o interogare SQL separată pentru fiecare element al listei. Se rezolvă cu DataLoader — o utilitate pentru grupare și cache a interogărilor către bazele de date care combină interogările individuale într-una singură în lot. În REST, această problemă este mai puțin pronunțată, deoarece dezvoltatorul controlează structura răspunsului pe server.
Să examinăm exemple practice de utilizare a GraphQL într-o aplicație mobilă în Kotlin cu Apollo Client. Exemplele demonstrează scenarii tipice: încărcarea datelor pentru ecranul de profil (query), crearea unei noi postări (mutation) și abonarea la comentarii noi (subscription). Fiecare exemplu include atât interogarea GraphQL, cât și codul pe partea clientului.
O singură interogare GraphQL încarcă utilizatorul, ultimele sale postări și numărul total de urmăritori. În REST ar fi necesare cel puțin 2-3 cereri: /users/42, /users/42/posts, /users/42/stats. GraphQL le combină într-un singur round-trip, reducând timpul de încărcare a ecranului pe conexiuni lente.
// Interogare GraphQL (în fișierul .graphql)
query ProfileScreen($userId: ID!) {
user(id: $userId) {
name
bio
avatarUrl
posts(limit: 10) {
id
title
createdAt
}
followersCount
followingCount
}
}
// Apel pe client (Apollo Client + Kotlin)
val response = apolloClient
.query(ProfileScreenQuery(userId = "42"))
.execute()
binding.nameText.text = response.data?.user?.name
Mutația nu doar creează resursa, ci și returnează datele sale actuale pentru actualizarea UI. Câmpul __typename este folosit de Apollo Client pentru normalizarea cache-ului — clientul actualizează automat înregistrarea Post în cache la primirea unui răspuns de succes al mutației.
// Mutație GraphQL
mutation CreatePost($input: CreatePostInput!) {
createPost(input: $input) {
id
title
createdAt
author {
id
name
}
}
}
// Apelul mutației cu tip de intrare
val input = CreatePostInput(
title = "Postare nouă despre GraphQL",
content = "GraphQL simplifică lucrul cu API-ul..."
)
val result = apolloClient
.mutation(CreatePostMutation(input))
.execute()
Un avantaj important al GraphQL față de REST în contextul dezvoltării mobile este generarea automată de cod. Apollo Client pentru Kotlin (Apollo GraphQL) generează clase tip-securizate din fișierele .graphql în etapa de compilare. Dacă serverul modifică schema, proiectul nu se va compila până la actualizarea interogărilor. Acest lucru previne erorile de runtime, caracteristice REST, unde modificarea structurii răspunsului poate rămâne neobservată în timpul dezvoltării.
Ecosistemul GraphQL include câteva biblioteci și instrumente cheie care simplifică dezvoltarea și exploatarea. Apollo Client — cea mai populară bibliotecă client, care suportă React, iOS, Android și Kotlin Multiplatform. Relay de la Facebook — o alternativă pentru aplicațiile React cu o abordare unică de gestionare a datelor și cache. Alegerea între Apollo și Relay depinde de platformă și de cerințele de performanță.
Pe partea de server conduc Apollo Server (Node.js), Netflix DGS Framework (Kotlin/Java) și graphql-ruby. Pentru dezvoltarea schemei și testarea interogărilor se folosește GraphiQL — un IDE interactiv încorporat în browser. Apollo Studio oferă metrici de performanță, urmărirea interogărilor și gestionarea schemei pentru mediul de producție. Separat, merită menționat GraphQL Code Generator — un instrument care generează tipuri TypeScript, Kotlin, Swift și Dart din schema SDL.
Pentru dezvoltarea mobilă prezintă un interes deosebit Apollo Kotlin (Apollo GraphQL) — o bibliotecă scrisă integral în Kotlin cu suport pentru corutine, Flow și Multiplatform. Aceasta permite utilizarea acelorași interogări GraphQL pentru Android și iOS în proiecte Kotlin Multiplatform. Apollo Kotlin normalizează cache-ul, suportă erorile la nivel de câmp (partial errors) și generează automat modele de date din fișierele .graphql. Acest lucru face din GraphQL alegerea preferată pentru proiecte mobile mari, unde viteza de dezvoltare și siguranța tipurilor sunt importante.
Întrebări frecvente
GraphQL nu înlocuiește REST, ci oferă o abordare alternativă. REST este mai potrivit pentru API-uri CRUD simple, cache prin HTTP și API-uri publice cu sarcină previzibilă. GraphQL este optim pentru interfețe complexe cu multe date conexe.
Migrarea este posibilă treptat: GraphQL poate funcționa ca strat intermediar (gateway) în fața serviciilor REST existente. Multe companii adaugă GraphQL pe lângă REST, fără a dezactiva API-ul vechi. Înlocuirea completă necesită rescrierea rezolvătoarelor.
N+1 apare atunci când pentru fiecare element al listei se execută o interogare separată la baza de date. Se rezolvă cu DataLoader — o bibliotecă care grupează interogările individuale într-una singură și stochează în cache rezultatele în cadrul unei singure cereri HTTP.
Specificația GraphQL nu definește direct încărcarea fișierelor. În practică se folosesc: codificarea base64 (simplă, dar ineficientă pentru fișiere mari), cereri multipart conform protocolului graphql-multipart-request-spec sau un endpoint REST separat pentru fișiere.
Securitatea GraphQL necesită măsuri suplimentare: limitarea adâncimii de imbricare, limita de complexitate a interogării, rate limiting la nivel de operații. Introspecția publică a schemei poate dezvălui structura datelor — în producție se recomandă dezactivarea acesteia.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și