3D Baskı için Model Hazırlama: STL Optimizasyonu
API Tasarımında Yeni Dönem
Modern yazılım geliştirme dünyasında API'ler, uygulamalar arasındaki iletişimin temel taşlarını oluşturur. Yıllardır REST mimarisi bu alanda standart olarak kabul edilse de, Facebook tarafından 2015 yılında açık kaynak olarak sunulan GraphQL, API tasarımına tamamen farklı bir bakış açısı getirdi. Peki hangi yaklaşım sizin projeniz için daha uygun? Bu rehberde her iki teknolojiyi derinlemesine karşılaştıracağız.
REST Nedir?
REST (Representational State Transfer), Roy Fielding tarafından 2000 yılında doktora tezinde tanımlanan bir mimari stildir. REST, HTTP protokolünün doğal yapısını kullanarak kaynaklara (resources) erişim sağlar. Her kaynak benzersiz bir URL ile temsil edilir ve standart HTTP metodları (GET, POST, PUT, DELETE) ile üzerinde işlemler gerçekleştirilir.
Tipik bir REST API'sinde endpoint'ler şu şekilde yapılandırılır:
GET /api/users → Tüm kullanıcıları listele
GET /api/users/42 → 42 ID'li kullanıcıyı getir
POST /api/users → Yeni kullanıcı oluştur
PUT /api/users/42 → 42 ID'li kullanıcıyı güncelle
DELETE /api/users/42 → 42 ID'li kullanıcıyı sil
GET /api/users/42/posts → 42 ID'li kullanıcının yazılarını getir
GraphQL Nedir?
GraphQL, hem bir sorgu dili hem de bu sorguları çalıştırmak için bir runtime'dır. REST'in aksine, GraphQL tek bir endpoint üzerinden çalışır ve istemcinin tam olarak hangi veriyi istediğini belirtmesine olanak tanır. Sunucu tarafında bir şema (schema) tanımlanır ve istemciler bu şemaya uygun sorgular gönderir.
Bir GraphQL sorgusu şu şekilde görünür:
query {
user(id: 42) {
name
email
posts {
title
createdAt
comments {
content
author {
name
}
}
}
}
}
Bu tek sorgu ile kullanıcı bilgileri, yazıları, yorumları ve yorum yazarlarının isimleri tek bir istekte alınabilir. REST ile aynı veriyi elde etmek için birden fazla endpoint'e istek göndermek gerekebilirdi.
Temel Farklar
1. Veri Çekme (Fetching) Yaklaşımı
REST API'lerinde en sık karşılaşılan iki problem over-fetching ve under-fetching olarak adlandırılır. Over-fetching, bir endpoint'in ihtiyaç duyduğunuzdan fazla veri döndürmesidir. Örneğin, sadece kullanıcının adını göstermek istediğinizde tüm profil bilgilerinin gelmesi gibi. Under-fetching ise tek bir endpoint'in yeterli veriyi sağlamaması nedeniyle birden fazla istek yapma zorunluluğudur.
GraphQL bu iki sorunu kökünden çözer. İstemci tam olarak hangi alanları istediğini belirtir ve sunucu yalnızca o alanları döndürür:
// Sadece isim ve email gerekiyorsa
query {
user(id: 42) {
name
email
}
}
// Profil sayfası için daha fazla alan gerekiyorsa
query {
user(id: 42) {
name
email
avatar
bio
followerCount
posts(limit: 5) {
title
summary
}
}
}
2. Endpoint Yapısı
REST, kaynak başına ayrı endpoint'ler tanımlar. Proje büyüdükçe endpoint sayısı hızla artar ve bunların yönetimi zorlaşabilir. GraphQL ise tek bir endpoint (/graphql) üzerinden tüm işlemleri gerçekleştirir. Tüm veri erişimi şema üzerinden yönetilir.
3. Tip Sistemi ve Şema
GraphQL'in en güçlü yanlarından biri, güçlü tip sistemine sahip olmasıdır. Şema tanımı SDL (Schema Definition Language) ile yapılır:
type User {
id: ID!
name: String!
email: String!
age: Int
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
createdAt: DateTime!
}
type Comment {
id: ID!
content: String!
author: User!
}
type Query {
user(id: ID!): User
users(limit: Int, offset: Int): [User!]!
post(id: ID!): Post
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: UpdateUserInput!): User!
deleteUser(id: ID!): Boolean!
}
Bu şema aynı zamanda otomatik dokümantasyon görevi görür. REST tarafında ise OpenAPI (Swagger) gibi ek araçlara ihtiyaç duyulur.
4. Sürüm Yönetimi (Versioning)
REST API'lerinde değişiklik yapmak genellikle yeni bir sürüm oluşturmayı gerektirir (/api/v1/users, /api/v2/users). Bu durum bakım yükünü artırır ve eski sürümlerin ne zaman devre dışı bırakılacağı her zaman tartışma konusudur.
GraphQL'de sürümleme ihtiyacı büyük ölçüde ortadan kalkar. Yeni alanlar eklenmesi mevcut sorguları bozmaz. Kaldırılması gereken alanlar @deprecated direktifi ile işaretlenir ve istemcilere geçiş süresi tanınır.
Performans Karşılaştırması
REST'in Avantajları
- HTTP önbellekleme: REST, HTTP'nin yerleşik önbellekleme mekanizmalarından (ETag, Cache-Control, Last-Modified) doğrudan faydalanır. Her endpoint için bağımsız önbellekleme stratejileri tanımlanabilir.
- CDN desteği: GET istekleri kolayca CDN katmanlarında önbelleklenebilir, bu da küresel ölçekte düşük gecikme süreleri sağlar.
- Basitlik: Basit CRUD operasyonları için REST daha az karmaşıklık sunar. Resolver yapısı, DataLoader gibi ek katmanlar gerekmez.
GraphQL'in Avantajları
- Ağ verimliliği: Tek bir istekte ihtiyaç duyulan tüm veri alınabilir. Mobil uygulamalar gibi bant genişliğinin kısıtlı olduğu ortamlarda bu kritik bir avantajdır.
- N+1 sorgu optimizasyonu: DataLoader gibi araçlarla veritabanı sorgularını toplu hale getirmek mümkündür.
- İstemci odaklı performans: Her istemci (web, mobil, IoT) tam olarak ihtiyacı olan veriyi çeker, fazlasını değil.
Sunucu Tarafı Uygulama Örnekleri
Node.js ile basit bir REST API:
const express = require('express');
const app = express();
app.get('/api/users/:id', async (req, res) => {
const user = await db.users.findById(req.params.id);
if (!user) return res.status(404).json({ error: 'Kullanıcı bulunamadı' });
res.json(user);
});
app.get('/api/users/:id/posts', async (req, res) => {
const posts = await db.posts.findByUserId(req.params.id);
res.json(posts);
});
app.listen(3000);
Aynı işlevselliğin GraphQL karşılığı (Apollo Server ile):
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
}
type Query {
user(id: ID!): User
}
`;
const resolvers = {
Query: {
user: (_, { id }) => db.users.findById(id),
},
User: {
posts: (parent) => db.posts.findByUserId(parent.id),
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen();
Güvenlik Konuları
Her iki yaklaşımın da kendine özgü güvenlik endişeleri vardır:
REST Güvenliği
- Standart HTTP güvenlik başlıkları ve CORS yapılandırması yeterlidir
- Rate limiting endpoint bazında kolayca uygulanır
- Yetkilendirme middleware seviyesinde yönetilebilir
GraphQL Güvenliği
- Sorgu derinliği sınırlaması: Kötü niyetli kullanıcılar iç içe geçmiş derin sorgularla sunucuyu zorlayabilir. Mutlaka maksimum derinlik sınırı koyulmalıdır.
- Sorgu karmaşıklığı analizi: Her alanın bir maliyeti (cost) hesaplanarak toplam sorgu maliyetine üst sınır konulmalıdır.
- Introspection kontrolü: Üretim ortamında şema introspection özelliği kapatılmalı veya sınırlandırılmalıdır.
- Persisted queries: Sadece önceden tanımlanmış sorguların çalıştırılmasına izin verilebilir.
Gerçek Zamanlı Veri
GraphQL, Subscription mekanizması ile gerçek zamanlı veri akışını doğal olarak destekler:
subscription {
messageAdded(channelId: "genel") {
id
content
author {
name
}
createdAt
}
}
REST tarafında gerçek zamanlı iletişim için WebSocket, Server-Sent Events (SSE) veya long-polling gibi ek mekanizmaların ayrıca entegre edilmesi gerekir.
Ne Zaman Hangisini Seçmeli?
REST tercih edin eğer:
- Projeniz basit CRUD operasyonlarından oluşuyorsa
- HTTP önbellekleme kritik önem taşıyorsa
- Ekibiniz REST konusunda deneyimli ama GraphQL'e yeni ise
- Dosya yükleme/indirme yoğun bir API geliştiriyorsanız
- Mikro servis mimarisinde servisler arası iletişim kuruyorsanız
- Üçüncü taraf geliştiricilere açık, kolay anlaşılır bir API sunmak istiyorsanız
GraphQL tercih edin eğer:
- Birden fazla istemci (web, mobil, tablet) farklı veri ihtiyaçlarına sahipse
- İlişkisel ve iç içe geçmiş veri yapılarınız varsa
- Frontend ekibi hızlı iterasyon yapmak istiyorsa ve backend değişikliği beklemek istemiyorsa
- Bant genişliği optimizasyonu önemliyse (özellikle mobil)
- Güçlü tip sistemi ve otomatik dokümantasyon istiyorsanız
- Gerçek zamanlı veri akışı gereksinimleriniz varsa
Hibrit Yaklaşım
Pratikte birçok büyük ölçekli uygulama her iki teknolojiyi birlikte kullanır. Örneğin, dosya yükleme ve webhook'lar için REST endpoint'leri korurken, veri sorgulama ve manipülasyon için GraphQL kullanabilirsiniz. GitHub, Shopify ve Atlassian gibi şirketler hem REST hem de GraphQL API'lerini paralel olarak sunmaktadır.
Bir diğer popüler yaklaşım ise BFF (Backend for Frontend) desenidir: mikro servisler kendi aralarında REST veya gRPC ile iletişim kurarken, istemcilere bakan katmanda bir GraphQL gateway konumlandırılır. Bu gateway, farklı servislerden gelen verileri birleştirerek istemciye tek bir GraphQL endpoint'i üzerinden sunar.
Sonuç
GraphQL ve REST arasında mutlak bir kazanan yoktur. Her iki teknoloji de farklı senaryolarda güçlü ve zayıf yönlere sahiptir. Doğru seçim; projenizin gereksinimleri, ekibinizin deneyimi, istemci çeşitliliği ve performans beklentilerinize bağlıdır. Önemli olan, her iki yaklaşımın avantajlarını ve sınırlamalarını anlamak ve projenizin ihtiyaçlarına en uygun çözümü bilinçli bir şekilde seçmektir.
API tasarımı, yazılım mimarisinin en kritik kararlarından biridir. Bu kararı verirken sadece bugünün değil, projenizin gelecekteki ölçekleme ihtiyaçlarını ve ekibinizin sürdürülebilirlik kapasitesini de göz önünde bulundurun.