GraphQL Nedir ve Nasıl Çalışır?
GraphQL, modern web uygulamaları için bir veri sorgulama ve manipülasyon dilidir. Facebook tarafından geliştirilen GraphQL, istemcilerin tam olarak ihtiyaç duydukları verileri alabilmelerini sağlar. Bu yazıda, GraphQL’in temel kavramlarına ve nasıl çalıştığına odaklanacağız.
1. GraphQL Temel Kavramları
GraphQL, modern web uygulamaları için bir veri sorgulama ve manipülasyon dilidir. Bu bölümde, GraphQL’in temel kavramlarına daha yakından bakacağız.
1.1 Şema (Schema)
GraphQL’de, bir şema veri modelini ve erişilebilir alanları tanımlar. Şema, GraphQL sorgularının ve mutasyonlarının nasıl görünmesi gerektiğini belirler. Şema, veri tipleri, alanlar ve ilişkileri içeren bir yapıya sahiptir. Bu şekilde, GraphQL sunucusu istemcilere hangi veriye erişebileceklerini açıkça tanımlayarak daha iyi kontrol sağlar.
1.2 Alanlar (Fields)
Alanlar, GraphQL’deki veri birimlerini temsil eder. Her bir alan, bir veri tipine ait olup, belirli bir değer döndürür. Örneğin, bir kullanıcı alanı, kullanıcının adını, e-posta adresini ve diğer bilgilerini içerebilir. Alanlar, ağaç benzeri bir yapıda hiyerarşik olarak gruplandırılabilir, böylece istemciler yalnızca ihtiyaç duydukları alanları seçebilir.
1.3 Sorgular (Queries)
Sorgular, GraphQL’de veri talebi yapmak için kullanılır. İstemci, sorgu gövdesinde istediği alanları belirtir ve sunucu yalnızca istemcinin talep ettiği veriyi döner. GraphQL, istemcilerin tam olarak ihtiyaç duydukları verileri almasını sağlayarak aşırı yükleme sorununu önler. Sorgular, veriye okuma işlemleri için kullanılır ve sunucunun geri dönüş değerini belirlemek için şemadaki ilgili alanların çözülmesine dayanır.
1.4 Mutasyonlar (Mutations)
Mutasyonlar, GraphQL’de veri değişikliği yapmak için kullanılır. Mutasyonlar, veri eklemek, güncellemek veya silmek gibi değişiklikleri gerçekleştirmek için kullanılır. İstemci, mutasyon sorgusu aracılığıyla değişiklik yapmak istediği alanları ve değerleri belirtir. Mutasyonlar, sunucunun istemciye geri dönüş değerini sağlayarak değişikliklerin başarılı olup olmadığını veya hataların oluşup oluşmadığını bildirebilir.
1.5 Argümanlar (Arguments)
Argümanlar, sorgu veya mutasyonların parametrelerini temsil eder. İstemci, sorgu veya mutasyon gövdesinde argümanları belirterek belirli bir işlemi veya filtrelemeyi sağlayabilir. Örneğin, belirli bir kullanıcının bilgilerini almak için kullanıcı kimliği argümanı kullanılabilir.
2. GraphQL Sorguları
GraphQL, istemcinin veriye erişimini sorgular aracılığıyla sağlar. Sorgular, istemcinin ihtiyaç duyduğu veri yapısını belirler ve sadece istenilen alanları almak için kullanılır.
2.1 Basit Sorgular
GraphQL’de basit bir sorgu şu şekilde görünebilir:
query {
user {
id
name
email
}
}
Bu sorgu, “user” alanından “id”, “name” ve “email” alanlarını istemektir.
2.2 Argümanlı Sorgular
Sorgular argümanlarla da genişletilebilir. Örneğin:
query {
user(id: 123) {
id
name
email
}
}
Bu sorgu, “user” alanından ID’si 123 olan kullanıcının “id”, “name” ve “email” alanlarını istemektir.
2.3 İlişkili Veri Sorgulama
GraphQL, ilişkili verileri sorgulamak için kullanışlıdır. Örneğin:
query {
user(id: 123) {
id
name
email
posts {
id
title
content
}
}
}
Bu sorgu, belirli bir kullanıcının tüm gönderilerini getirir.
3. GraphQL Mutasyonları
GraphQL, veri üzerinde değişiklik yapmak için mutasyonları kullanır. Mutasyonlar, veri ekleme, güncelleme veya silme gibi değişiklikleri gerçekleştirebilir.
3.1 Ekleme Mutasyonları
Örneğin, yeni bir kullanıcı eklemek için aşağıdaki gibi bir mutasyon kullanılabilir:
mutation {
addUser(name: "John Doe", email: "john.doe@example.com") {
id
name
email
}
}
Bu mutasyon, yeni eklenen kullanıcının “id”, “name” ve “email” alanlarını döndürür.
3.2 Güncelleme Mutasyonları
Bir veriyi güncellemek için mutasyonlar kullanılabilir. Örneğin:
mutation {
updateUser(id: 123, name: "Jane Smith") {
id
name
email
}
}
Bu mutasyon, ID’si 123 olan bir kullanıcının adını günceller.
3.3 Silme Mutasyonları
GraphQL ile veri silmek için mutasyonlar kullanılabilir. Örneğin:
mutation {
deleteUser(id: 123) {
id
name
email
}
}
Bu mutasyon, ID’si 123 olan bir kullanıcıyı siler.
4. GraphQL ve Sunucu Uygulaması
GraphQL, bir sunucu uygulamasıyla birlikte kullanılabilir. Sunucu tarafında, şemalar ve resolver fonksiyonları tanımlanır. İstemci, belirli veri gereksinimlerini sunucuya gönderir ve sunucu bu verileri geri döner.
4.1 Sunucu İmplementasyonu
GraphQL sunucusu geliştirmek için popüler dil ve çerçeveler kullanılabilir. Node.js için Express veya Apollo Server, Python için Django veya Flask, Ruby için Ruby on Rails gibi çeşitli seçenekler vardır.
4.2 Resolver Fonksiyonları
Resolver fonksiyonları, GraphQL şemasındaki alanları çözen ve ilgili verileri döndüren fonksiyonlardır. Bu fonksiyonlar, veritabanı sorguları veya harici API çağrıları gibi işlemleri gerçekleştirir.
4.3 Şema Tanımlama
GraphQL sunucusunda, şemalar tanımlanır. Şemalar, sunucunun hangi veri tiplerini ve alanları desteklediğini belirler. Şema tanımlamasında GraphQL SDL (Schema Definition Language) kullanılır.
5. GraphQL Ekosistemi
GraphQL’in geniş bir ekosistemi vardır ve birçok araç ve kütüphane mevcuttur. Bunlar, GraphQL sunucusu ve istemci geliştirmeyi kolaylaştırır, otomatik dökümantasyon sağlar ve sorguların performansını iyileştirir.
NodeJS İle GraphQL Uygulaması
Proje Kurulumu
Öncelikle, Node.js ve npm’i bilgisayarınıza kurmanız gerekmektedir. Bu adımları tamamladıktan sonra yeni bir Node.js projesi oluşturarak gerekli bağımlılıkları yükleyin. Bu adımları takip etmek için aşağıdaki komutları kullanabilirsiniz:
$ mkdir nodejs-graphql-api
$ cd nodejs-graphql-api
$ npm init -y
$ npm install express graphql express-graphql
İlk olarak, bir proje klasörü oluşturuyoruz ve bu klasöre geçiyoruz. Ardından, npm init -y
komutunu kullanarak bir package.json
dosyası oluşturuyoruz. Bu dosya, proje bağımlılıklarını ve diğer ayarları içerir. Son olarak, npm install
komutuyla gerekli bağımlılıkları yükleyin. Bu projede, Express, GraphQL ve express-graphql paketlerini kullanacağız.
GraphQL Schema Oluşturma
Şimdi, GraphQL şemamızı oluşturmak için schema.graphql
adında bir dosya oluşturalım. Bu dosya, API’nin kullanacağı veri modellerini ve şema tanımlarını içerecektir. Örneğimizde, Movie
adında bir veri modelimiz olacak. Her film, id
, title
, director
ve year
alanlarına sahip olacak. Ayrıca, sorgu ve mutasyon tipleri için de şema tanımları yapacağız.
type Movie {
id: ID!
title: String!
director: String!
year: Int!
}
type Query {
movie(id: ID!): Movie
movies: [Movie]
}
type Mutation {
addMovie(title: String!, director: String!, year: Int!): Movie
updateMovie(id: ID!, title: String, director: String, year: Int): Movie
}
Bu şemada, Movie
adında bir tip tanımladık. Bu tip, her bir film için gerekli olan alanları içerir. Ardından, Query
tipiyle sorgu işlemlerini tanımladık. movie
alanı, belirli bir filmi ID’ye göre sorgulamak için kullanılırken, movies
alanı tüm filmleri döndürmek için kullanılır. Son olarak, Mutation
tipiyle mutasyon işlemlerini tanımladık. addMovie
alanı yeni bir film eklemek için kullanılırken, updateMovie
alanı mevcut bir filmin bilgilerini güncellemek için kullanılır.
Express ve GraphQL Kullanarak API’nin Oluşturulması
API’yi oluşturmak için index.js
adında bir dosya oluşturalım. Bu dosya, Express ve GraphQL kullanarak API’yi oluşturacak olan kodları içerecektir. İlk olarak, gerekli paketleri import edelim ve şemayı oluşturalım.
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
// GraphQL Schema
const schema = buildSchema(`
type Movie {
id: ID!
title: String!
director: String!
year: Int!
}
type Query {
movie(id: ID!): Movie
movies: [Movie]
}
type Mutation {
addMovie(title: String!, director: String!, year: Int!): Movie
updateMovie(id: ID!, title: String, director: String, year: Int): Movie
}
`);
Bu kısımda, Express ve express-graphql paketlerini import ediyoruz. Ardından, buildSchema
fonksiyonunu kullanarak şemayı oluşturuyoruz. Şemada, Movie
tipi için alanları ve Query
ile Mutation
tipleri için işlemleri tanımlıyoruz.
Şema oluşturulduktan sonra, film verilerini tanımlayalım. Bu örnekte, basitçe birkaç film verisi oluşturacağız. Bu veriler, API üzerinden sorgulanabilecek film örneklerini temsil edecek.
// Movie Datas
const movies = [
{ id: '1', title: 'The Lord of the Rings: The Fellowship of the Ring', director: 'Peter Jackson', year: 2001 },
{ id: '2', title: 'The Shawshank Redemption', director: 'Frank Darabont', year: 1994 },
];
Daha sonra, resolver fonksiyonlarını tanımlayalım. Bu fonksiyonlar, sorgu ve mutasyon işlemlerini gerçekleştirecek kodları içerecektir. Resolver fonksiyonları, şemada tanımlanan alanlarla eşleşen fonksiyonlardır.
// Resolver Functions
const root = {
movie: ({ id }) => movies.find(movie=> movie.id === id),
movies: () => movies,
addMovie: ({ title, director, year }) => {
const newMovie = { id: movies.length + 1, title, director, year };
movies.push(newMovie);
return newMovie;
},
updateMovie: ({ id, title, director, year }) => {
const movieIndex = movies.findIndex(movie=> movie.id === id);
if (movieIndex === -1) throw new Error('Film bulunamadı');
const updateMovie = { ...movies[movieIndex], title, director, year };
movies[movieIndex] = updateMovie;
return updateMovie;
},
};
Sorgu ve mutasyon işlemleri için gerekli olan resolver fonksiyonlarını tanımladık. movie
fonksiyonu, belirli bir filmi ID’ye göre bulmak için kullanılırken, movies
fonksiyonu tüm filmleri döndürmek için kullanılır. addMovie
fonksiyonu yeni bir film eklemek için kullanılırken, updateMovie
fonksiyonu mevcut bir filmin bilgilerini güncellemek için kullanılır.
Son olarak, Express uygulamasını oluşturup GraphQL middleware’i ekleyelim ve sunucuyu dinlemeye başlayalım.
const app = express();
// GraphQL Middleware
app.use(
'/graphql',
graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
})
);
// Listen Server
app.listen(3000, () => {
console.log('API run on port :3000. API Url : http://localhost:3000/graphql');
});
Express uygulamasını oluşturuyoruz. Ardından, /graphql
endpoint’i üzerinden GraphQL middleware’ini ekliyoruz. Bu middleware, oluşturduğumuz şema (schema
), resolver fonksiyonları (rootValue
) ve GraphiQL arayüzünü (graphiql: true
) kullanarak API’yi oluşturur.
Son olarak, sunucuyu belirtilen port üzerinden dinlemeye başlıyoruz.
API’ye Erişim
API’yi başarıyla oluşturduktan sonra, tarayıcınızdan http://localhost:3000/graphql
adresine giderek API’ye erişebilirsiniz. GraphiQL arayüzünü göreceksiniz ve buradan örnek sorguları ve mutasyonları deneyebilirsiniz.
Örnek sorgu: Tüm filmleri almak için:
query {
movies {
id
title
director
year
}
}
Örnek mutasyon: Yeni bir film eklemek için:
mutation {
addMovie(title: "Inception", director: "Christopher Nolan", year: 2010) {
id
title
director
year
}
}
Bu örnekler, API’nin nasıl kullanıldığını göstermektedir. İstediğiniz sorguları ve mutasyonları deneyebilir ve API’nin sonuçlarını gözlemleyebilirsiniz.
Bu proje, Node.js ve GraphQL’in birlikte nasıl kullanıldığını göstermektedir. Express ile GraphQL’in entegrasyonu, API’lerin hızlı bir şekilde oluşturulmasını sağlar. GraphQL’in esnekliği sayesinde istemciler, ihtiyaç duydukları verileri özelleştirebilirler.
Projeye Github Üzerinden Erişim
Projeye ait kodları indirmek ve incelemek isterseniz Node.js GraphQL Example adresi üzerinden Github reposuna ulaşabilirsiniz.
Sonuç
Bu blog yazısında, GraphQL’in temel kavramlarına ve kullanımına odaklandık. Şema tanımlama, sorgular, mutasyonlar ve resolver fonksiyonları gibi konulara değindik. Ayrıca, GraphQL sunucusu oluşturmak ve istemcilerle iletişim kurmak için kullanılan araçlardan bahsettik ve bir NodeJS ile GraphQL örneği yazdık.
GraphQL, modern web uygulamalarında veri sorgulama ve manipülasyonu için güçlü bir araçtır. Esneklik, optimize etme ve aşırı yüklenmeyi önleme yetenekleriyle biz geliştiricilere büyük kolaylık sağlar.
Faydalı olması dileğiyle.