GraphQL — egy lekérdező nyelv API-hoz és egy futtatókörnyezet e lekérdezések végrehajtásához, amelyet a Facebook fejlesztett ki 2012-ben és nyílt forráskódúvá tett 2015-ben. Ellentétben a REST-tel, ahol a szerver határozza meg a válasz szerkezetét, a GraphQL lehetővé teszi a kliens számára, hogy pontosan megadja, milyen adatokra van szüksége, teljesen kiküszöbölve az overfetching és underfetching problémáit. A State of JavaScript Survey (2025) szerint a GraphQL-t a megkérdezett fejlesztők 35%-a használja, és a nagyvállalatok közül a GitHub, a Shopify, az Airbnb és a The New York Times vezette be. A GraphQL háromféle műveletet támogat: query (olvasás), mutation (írás) és subscription (valós idejű frissítések WebSocketen keresztül).
Főbb pontok
GraphQL — egy specifikáció és futtatókörnyezet API-hoz, amely teljes körű vezérlést ad a kliensnek a kapott adatok felett. A Facebook mérnökei fejlesztették ki a News Feed mobilalkalmazás problémáinak megoldására, a specifikációt 2015-ben nyílt szabványként tették közzé. 2018 óta a GraphQL a GraphQL Foundation irányítása alatt áll a Linux Foundation és olyan vállalatok támogatásával, mint az Apollo, az AWS, a GitHub, az SAP és mások.
Ellentétben a REST-tel, ahol minden endpoint rögzített adatszerkezetet ad vissza, a GraphQL egyetlen endpoint-ot használ, amely egy lekérdezési karakterláncot fogad. A kliens a lekérdezésben leírja, milyen mezőkre van szüksége, és a szerver pontosan azokat adja vissza. Például a { user(id: „1”) { name email } } lekérdezés csak a felhasználó name és email mezőit adja vissza, a REST-ben lekérdezendő address, phone vagy createdAt felesleges mezők nélkül.
A GraphQL nincs egyetlen adatbázishoz vagy nyelvhez kötve. A specifikáció csak a lekérdezések és válaszok formátumát határozza meg. Vannak szerver implementációk Node.js-ben (graphql-js, Apollo Server), Kotlin-ban (graphql-kotlin, Netflix DGS Framework), Python-ban (Graphene, Strawberry), Ruby-ban (graphql-ruby) és más nyelveken. A kliens könyvtárak elérhetők az összes főbb platformhoz, beleértve az Apollo Client-et iOS-re, Androidra és a webhez.
A GraphQL architektúrája három kulcsfontosságú összetevőből áll: séma (Schema), feloldók (Resolvers) és végrehajtó motor (GraphQL Engine). A séma meghatározza, milyen adattípusok érhetők el, milyen lekérdezések hajthatók végre és milyen argumentumokat fogadnak el. A feloldók a szerveren található függvények, amelyek adatokat adnak vissza a séma minden mezőjéhez. A végrehajtó motor fogadja a bejövő lekérdezést, érvényesíti a séma alapján, meghívja a megfelelő feloldókat és összeállítja a választ.
A lekérdezés feldolgozási folyamata így néz ki:
A GraphQL architektúra legfőbb előnye a mezőszintű feloldás. A REST-ben a fejlesztő vagy megkapja az erőforrás összes mezőjét (esetleg feleslegesen), vagy kiterjesztésekhez folyamodik, mint a ?fields=name,email. A GraphQL-ben az ilyen szűrés be van építve a nyelvbe: minden lekérdezés kifejezetten meghatározza, mely mezők szükségesek, és a szerver pontosan azokat adja vissza. Ez különösen fontos a mobilalkalmazásoknál, ahol az átvitt adatok mennyisége közvetlenül befolyásolja a betöltési sebességet és az adatforgalmat.
A GraphQL háromféle műveletet határoz meg, amelyek mindegyike egy adott interakciós forgatókönyvnek felel meg. Query — adatok olvasására, analóg a GET-tel a REST-ben. Mutation — adatok módosítására (létrehozás, frissítés, törlés), analóg a POST/PUT/DELETE-tel. Subscription — valós idejű frissítésekre WebSocketen keresztül, aminek nincs közvetlen analógiája a klasszikus REST-ben (további megoldásokat igényel, mint a WebSocket vagy a Server-Sent Events).
A lekérdezések alapvető szintaxisa intuitív:
// Egyszerű lekérdezés argumentummal
query {
user(id: "42") {
name
email
avatarUrl
}
}
// Mutation a módosított adatok visszaadásával
mutation {
updateProfile(name: "Iván") {
id
name
updatedAt
}
}
// Subscription — valós idejű frissítéseket figyel
subscription {
newMessage(chatId: "chat_1") {
id
text
sender { name }
}
}
A Query párhuzamosan hajtódik végre — az összes mező ugyanazon a szinten egyszerre töltődik be. Ez lehetővé teszi kapcsolódó adatok (felhasználó és bejegyzései) betöltését egyetlen lekérdezéssel, többszörös round-trip nélkül. A Mutation szekvenciálisan hajtódik végre — a mutációk egy lekérdezésben egymás után, a deklarálás sorrendjében hajtódnak végre. A Subscription állandó kapcsolatot hoz létre WebSocketen keresztül, amelyen keresztül a szerver adatokat küld, amikor egy esemény bekövetkezik.
A műveletek fogadhatnak változókat az adatok lekérdezéstől való elválasztására, direktívákat (@include, @skip) a mezők feltételes belefoglalására és töredékeket a mezőkészletek újrafelhasználására. Ezek a képességek rugalmassá és újrafelhasználhatóvá teszik a GraphQL lekérdezéseket, ami különösen fontos a több képernyővel és komponenssel rendelkező nagy projektekben.
A GraphQL középpontjában a típusrendszer áll, amely leírja az API összes lehetséges adatát és műveletét. A séma (Schema) a szerver által visszaadható típusok és a fogadott lekérdezések leírása. A séma a Schema Definition Language (SDL) nyelven íródik, és szerződésként szolgál a kliens és a szerver között. A kliens a sémát introspekcióval — egy speciális __schema lekérdezéssel szerezheti meg, amely az API teljes leírását adja vissza.
Példa sémára egy bloghoz:
// 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!]!
}
A felkiáltójel (!) non-null mezőt jelent — garantáltan jelen lesz a válaszban. A szögletes zárójelek [ ] listát jelölnek. A GraphQL skaláris típusokat (Int, Float, String, Boolean, ID), objektum típusokat, enum, union, interface és input-típusokat (mutációs argumentumokhoz) támogat. A szigorú típusosság öndokumentálóvá teszi az API-t, és lehetővé teszi a kliens eszközök számára a kód generálását: TypeScript típusok, Kotlin adatosztályok, Swift struktúrák.
Introspekció — a GraphQL egyedülálló képessége, amely hiányzik a REST-ből. A kliens lekérdezést küldhet a sémának, és teljes leírást kaphat az összes típusról, mezőről, argumentumról és direktíváról. Ez képezi az olyan eszközök alapját, mint a GraphiQL és az Apollo Studio, amelyek automatikusan dokumentációt és automatikus kiegészítést generálnak a fejlesztők számára. Az introspekció lehetővé teszi továbbá automatikus tesztek írását is, amelyek ellenőrzik a séma megfelelését a várt szerkezetnek.
A GraphQL és REST közötti választás az egyik kulcsfontosságú architekturális kérdés az API tervezésekor. Mindkét megközelítésnek megvannak az erősségei és gyengeségei, és a választás a projekt konkrét követelményeitől függ. A REST az egyszerűségben és univerzalitásban nyer, a GraphQL a rugalmasságban és a lekérdezés hatékonyságában. Nézzük meg az összehasonlító táblázatot.
| Szempont | REST | GraphQL |
|---|---|---|
| Válasz szerkezete | Rögzített, szerveroldali | Rugalmas, kliensoldali |
| Overfetching | Gyakran — a szerver minden mezőt visszaad | Nem — a kliens csak a szükségeseket kéri |
| Kérések száma | Többszörös round-trip | Egy kérés az összes adatra |
| Gyorsítótárazás | Natív HTTP gyorsítótárazás | Kézi konfigurációt igényel |
| Típusosság | Nincs beépítve (formátumfüggő) | Szigorú, SDL séma segítségével |
| Eszközök | curl, Postman, Swagger | GraphiQL, Apollo Studio, Introspection |
| Fájlfeltöltés | Natív multipart segítségével | További protokollokat igényel |
| Teljesítmény | Kiszámítható, könnyebb optimalizálni | Függ az egymásba ágyazott lekérdezések összetettségétől |
A GraphQL fő hátránya a gyorsítótárazás nehézsége. A REST-ben a HTTP-gyorsítótárazás URL szinten működik: egy kérés a /api/users/42 címre mindig ugyanazt a szerkezetet adja vissza, és a válasz URL alapján gyorsítótárazható. A GraphQL-ben minden kérés egyetlen endpoint-ra megy, a válasz szerkezete a kérés törzsétől függ. A probléma megoldására az Apollo Client normalizált gyorsítótárat használ a kliens oldalon, amely a válaszokat id alapján külön entitásokra bontja, és automatikusan frissíti azokat új adatok érkezésekor.
Egy másik fontos szempont az N+1 probléma. Egymásba ágyazott adatok (például a felhasználó bejegyzései és az egyes bejegyzésekhez tartozó megjegyzések) lekérésekor a GraphQL külön SQL lekérdezést hajthat végre a lista minden eleméhez. Ezt a DataLoader oldja meg — egy segédprogram az adatbázis-lekérdezések kötegelésére és gyorsítótárazására, amely az egyes lekérdezéseket egy kötegelt lekérdezésbe csoportosítja. A REST-ben ez a probléma kevésbé kifejezett, mivel a fejlesztő a szerver oldalon ellenőrzi a válasz szerkezetét.
Vizsgáljuk meg a GraphQL gyakorlati használatának példáit egy Kotlinban készült mobilalkalmazásban Apollo Client segítségével. A példák tipikus forgatókönyveket mutatnak be: adatok betöltése a profilképernyőhöz (query), új bejegyzés létrehozása (mutation) és feliratkozás új megjegyzésekre (subscription). Minden példa tartalmazza a GraphQL lekérdezést és a kliens oldali kódot is.
Egy GraphQL lekérdezés betölti a felhasználót, legutóbbi bejegyzéseit és a követők teljes számát. A REST-ben ehhez legalább 2-3 kérésre lenne szükség: /users/42, /users/42/posts, /users/42/stats. A GraphQL ezeket egy round-trip-be egyesíti, csökkentve a képernyő betöltési idejét lassú kapcsolatokon.
// GraphQL lekérdezés (.graphql fájlban)
query ProfileScreen($userId: ID!) {
user(id: $userId) {
name
bio
avatarUrl
posts(limit: 10) {
id
title
createdAt
}
followersCount
followingCount
}
}
// Kliens oldali hívás (Apollo Client + Kotlin)
val response = apolloClient
.query(ProfileScreenQuery(userId = "42"))
.execute()
binding.nameText.text = response.data?.user?.name
A mutáció nemcsak létrehozza az erőforrást, hanem visszaadja annak aktuális adatait a UI frissítéséhez. A __typename mezőt az Apollo Client a gyorsítótár normalizálásához használja — a kliens automatikusan frissíti a Post rekordot a gyorsítótárban a mutáció sikeres válaszának fogadásakor.
// GraphQL mutáció
mutation CreatePost($input: CreatePostInput!) {
createPost(input: $input) {
id
title
createdAt
author {
id
name
}
}
}
// Mutáció hívása input-típussal
val input = CreatePostInput(
title = "Új bejegyzés a GraphQL-ről",
content = "A GraphQL leegyszerűsíti az API-val való munkát..."
)
val result = apolloClient
.mutation(CreatePostMutation(input))
.execute()
A GraphQL fontos előnye a REST-tel szemben a mobilfejlesztés kontextusában az automatikus kódgenerálás. Az Apollo Client Kotlinhoz (Apollo GraphQL) típusbiztos osztályokat generál .graphql fájlokból a buildelés során. Ha a szerver megváltoztatja a sémát, a projekt nem épül fel, amíg a lekérdezések frissítésre nem kerülnek. Ez megakadályozza a futásidejű hibákat, amelyek jellemzőek a REST-re, ahol a válasz szerkezetének megváltozása észrevétlen maradhat a fejlesztés során.
A GraphQL ökoszisztéma számos kulcsfontosságú könyvtárat és eszközt foglal magában, amelyek leegyszerűsítik a fejlesztést és az üzemeltetést. Apollo Client — a legnépszerűbb kliens könyvtár, amely támogatja a React, iOS, Android és Kotlin Multiplatform platformokat. A Facebook Relay terméke — alternatíva React alkalmazásokhoz, egyedi adatkezelési és gyorsítótárazási megközelítéssel. Az Apollo és a Relay közötti választás a platformtól és a teljesítménykövetelményektől függ.
A szerver oldalon az Apollo Server (Node.js), a Netflix DGS Framework (Kotlin/Java) és a graphql-ruby vezet. A séma fejlesztéséhez és a lekérdezések teszteléséhez a GraphiQL-t használják — egy interaktív IDE-t, amely a böngészőbe van beépítve. Az Apollo Studio teljesítménymutatókat, lekérdezés-követést és séma kezelést biztosít a termelési környezethez. Külön említést érdemel a GraphQL Code Generator — egy eszköz, amely TypeScript, Kotlin, Swift és Dart típusokat generál SDL sémákból.
A mobilfejlesztés szempontjából kiemelt érdeklődésre tart számot az Apollo Kotlin (Apollo GraphQL) — egy teljes egészében Kotlinban írt könyvtár coroutine, Flow és Multiplatform támogatással. Lehetővé teszi ugyanazon GraphQL lekérdezések használatát Androidra és iOS-re Kotlin Multiplatform projektekben. Az Apollo Kotlin normalizálja a gyorsítótárat, támogatja a mezőszintű hibákat (partial errors) és automatikusan adatmodelleket generál .graphql fájlokból. Ez teszi a GraphQL-t a preferált választássá nagy mobil projektekben, ahol a fejlesztési sebesség és a típusbiztonság fontos.
Gyakran ismételt kérdések
A GraphQL nem helyettesíti a REST-t, hanem alternatív megközelítést kínál. A REST egyszerű CRUD-API-khoz, HTTP-n keresztüli gyorsítótárazáshoz és nyilvános API-khoz alkalmas kiszámítható terheléssel. A GraphQL összetett, sok kapcsolódó adattal rendelkező felületekhez optimális.
A migráció fokozatosan lehetséges: a GraphQL működhet köztes rétegként (gateway) a meglévő REST szolgáltatások előtt. Sok vállalat a REST mellé adja hozzá a GraphQL-t, anélkül hogy kikapcsolná a régi API-t. A teljes csere a feloldók újraírását igényli.
N+1 akkor fordul elő, amikor a lista minden eleméhez külön adatbázis-lekérdezés fut. A DataLoader — egy olyan könyvtár oldja meg, amely az egyes lekérdezéseket egyetlen kötegbe csoportosítja és az eredményeket egy HTTP-kérés keretében gyorsítótárazza.
A GraphQL specifikáció nem határozza meg közvetlenül a fájlfeltöltést. A gyakorlatban a következőket használják: base64 kódolás (egyszerű, de nem hatékony nagy fájlok esetén), multipart kérések a graphql-multipart-request-spec protokoll szerint, vagy külön REST endpoint fájlok számára.
A GraphQL biztonsága további intézkedéseket igényel: a beágyazottság mélységének korlátozása, a lekérdezés összetettségének határértéke, műveleti szintű rate limiting. A séma nyilvános introspekciója felfedheti az adatok szerkezetét — éles környezetben ajánlott kikapcsolni.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is