REST Mimarisine Giriş
REST (Representational State Transfer), Roy Fielding tarafından 2000 yılında doktora tezinde tanımlanan bir mimari stildir. Web servislerinin tasarımında kullanılan en yaygın yaklaşım olan REST, HTTP protokolünün güçlü özelliklerini temel alarak istemci-sunucu iletişimini standartlaştırır. RESTful API'ler, modern web ve mobil uygulamaların bel kemiğini oluşturur; frontend ile backend arasındaki köprüyü kurar, üçüncü parti entegrasyonları mümkün kılar ve mikro servis mimarilerinde servisler arası iletişimi sağlar.
Bu rehberde, profesyonel ve sürdürülebilir RESTful API'ler tasarlamak için bilmeniz gereken en iyi uygulamaları ve standartları detaylı şekilde inceleyeceğiz.
REST'in Temel Prensipleri
Bir API'nin "RESTful" olarak nitelendirilebilmesi için belirli mimari kısıtlamalara uyması gerekir:
- İstemci-Sunucu Ayrımı: İstemci ve sunucu birbirinden bağımsız olmalıdır. İstemci veri sunum ve kullanıcı etkileşiminden, sunucu ise veri depolama ve iş mantığından sorumludur
- Durumsuzluk (Statelessness): Her istek, işlenmesi için gerekli tüm bilgiyi içermelidir. Sunucu, istekler arasında istemci durumu tutmaz
- Önbelleğe Alınabilirlik (Cacheability): Yanıtlar, önbelleğe alınabilir veya alınamaz olarak açıkça işaretlenmelidir
- Katmanlı Sistem: İstemci, doğrudan son sunucuyla mı yoksa aracı bir katmanla mı iletişim kurduğunu bilmek zorunda değildir
- Tekdüze Arayüz (Uniform Interface): Kaynaklar tutarlı bir şekilde tanımlanmalı ve manipüle edilmelidir
- İsteğe Bağlı Kod (Code on Demand): Sunucu, isteğe bağlı olarak çalıştırılabilir kod gönderebilir (bu kısıtlama isteğe bağlıdır)
HTTP Metotları ve Kullanımları
RESTful API'lerde HTTP metotları, kaynaklar üzerinde yapılacak işlemleri belirler. Her metot belirli bir semantiğe sahiptir ve doğru kullanımı API'nin tutarlılığı için kritiktir:
| HTTP Metodu | İşlem | Idempotent | Güvenli | Açıklama |
|---|---|---|---|---|
| GET | Okuma | Evet | Evet | Kaynak veya kaynak listesi getirir |
| POST | Oluşturma | Hayır | Hayır | Yeni kaynak oluşturur |
| PUT | Güncelleme (Tam) | Evet | Hayır | Kaynağın tamamını günceller |
| PATCH | Güncelleme (Kısmi) | Hayır | Hayır | Kaynağın belirli alanlarını günceller |
| DELETE | Silme | Evet | Hayır | Kaynağı siler |
| HEAD | Başlık Bilgisi | Evet | Evet | GET gibi ama yalnızca başlıkları döner |
| OPTIONS | Seçenekler | Evet | Evet | Desteklenen metotları listeler |
Idempotent ve Güvenli Metotlar
Bir metodun idempotent olması, aynı isteğin birden fazla kez gönderilmesinin tek bir kez gönderilmesiyle aynı sonucu vermesi demektir. PUT ve DELETE idempotent iken, POST idempotent değildir. Güvenli metotlar ise sunucu durumunu değiştirmeyen metotlardır (GET, HEAD, OPTIONS).
URL Tasarımı ve Kaynak Adlandırma
İyi tasarlanmış URL'ler, API'nin kullanılabilirliğini ve anlaşılabilirliğini doğrudan etkiler. URL tasarımında uyulması gereken kurallar:
Kaynak Adlandırma Kuralları
- Kaynaklar için çoğul isimler kullanın:
/users,/products,/orders - Fiil değil, isim kullanın:
/users(doğru),/getUsers(yanlış) - Küçük harf ve tire (-) kullanın:
/order-items(doğru),/orderItems(yanlış) - Hiyerarşik ilişkileri URL'de yansıtın:
/users/123/orders - Dosya uzantısı kullanmayın:
/users(doğru),/users.json(yanlış)
İyi URL Tasarımı Örnekleri
# Kullanıcı işlemleri
GET /api/v1/users # Tüm kullanıcıları listele
GET /api/v1/users/123 # ID'si 123 olan kullanıcıyı getir
POST /api/v1/users # Yeni kullanıcı oluştur
PUT /api/v1/users/123 # Kullanıcıyı tamamen güncelle
PATCH /api/v1/users/123 # Kullanıcıyı kısmen güncelle
DELETE /api/v1/users/123 # Kullanıcıyı sil
# İlişkisel kaynaklar
GET /api/v1/users/123/orders # Kullanıcının siparişleri
GET /api/v1/users/123/orders/456 # Belirli bir sipariş
POST /api/v1/users/123/orders # Yeni sipariş oluştur
# Filtreleme ve arama
GET /api/v1/products?category=electronics&sort=price
GET /api/v1/users?search=ahmet&page=2&limit=20
HTTP Durum Kodları
Doğru HTTP durum kodları kullanmak, API'nin istemciler tarafından doğru yorumlanmasını sağlar. Durum kodları beş kategoriye ayrılır:
2xx - Başarı Kodları
- 200 OK: İstek başarılı. GET, PUT, PATCH, DELETE için kullanılır
- 201 Created: Yeni kaynak başarıyla oluşturuldu. POST için kullanılır. Location başlığında yeni kaynağın URL'i döndürülmelidir
- 204 No Content: İstek başarılı ama döndürülecek içerik yok. DELETE işlemlerinde yaygın
4xx - İstemci Hata Kodları
- 400 Bad Request: İstek geçersiz veya eksik parametre içeriyor
- 401 Unauthorized: Kimlik doğrulama gerekli veya başarısız
- 403 Forbidden: Kimlik doğrulandı ama yetki yetersiz
- 404 Not Found: Kaynak bulunamadı
- 405 Method Not Allowed: HTTP metodu bu kaynak için desteklenmiyor
- 409 Conflict: İstek, mevcut kaynak durumuyla çakışıyor
- 422 Unprocessable Entity: İstek anlaşıldı ama semantik hatalar içeriyor
- 429 Too Many Requests: Rate limit aşıldı
5xx - Sunucu Hata Kodları
- 500 Internal Server Error: Sunucu tarafında beklenmeyen bir hata oluştu
- 502 Bad Gateway: Aracı sunucu, upstream sunucudan geçersiz yanıt aldı
- 503 Service Unavailable: Sunucu geçici olarak kullanılamıyor
- 504 Gateway Timeout: Aracı sunucu, upstream sunucudan zamanında yanıt alamadı
Versiyonlama Stratejileri
API versiyonlama, mevcut istemcileri bozmadan API'yi geliştirmenin yoludur. Yaygın versiyonlama stratejileri:
URL Tabanlı Versiyonlama
En yaygın ve en kolay anlaşılır yaklaşımdır:
GET /api/v1/users
GET /api/v2/users
Header Tabanlı Versiyonlama
URL'yi temiz tutar ancak keşfedilebilirliği azaltır:
GET /api/users
Accept: application/vnd.myapi.v2+json
Query Parameter Versiyonlama
GET /api/users?version=2
URL tabanlı versiyonlama, en yaygın kullanılan ve önerilen yaklaşımdır. Basit, açık ve araçlarla kolay test edilebilir olması en büyük avantajlarıdır.
Sayfalama (Pagination)
Büyük veri setlerinde tüm kayıtları tek seferde döndürmek performans ve kaynak kullanımı açısından sorunludur. Sayfalama stratejileri:
Offset Tabanlı Sayfalama
GET /api/v1/products?page=3&limit=20
{
"data": [...],
"pagination": {
"currentPage": 3,
"pageSize": 20,
"totalItems": 458,
"totalPages": 23
}
}
Cursor Tabanlı Sayfalama
Büyük veri setlerinde daha performanslı olan cursor tabanlı sayfalama, bir sonraki sayfa için bir işaretçi (cursor) kullanır:
GET /api/v1/products?cursor=eyJpZCI6MTAwfQ&limit=20
{
"data": [...],
"pagination": {
"nextCursor": "eyJpZCI6MTIwfQ",
"hasMore": true
}
}
Cursor tabanlı sayfalama, sosyal medya akışları gibi sürekli güncellenen veri setlerinde offset tabanlı sayfalamaya göre daha tutarlı sonuçlar verir.
Filtreleme ve Sıralama
API'lerin esnek veri sorgulama yetenekleri sunması, istemci tarafının işini kolaylaştırır:
# Filtreleme
GET /api/v1/products?category=electronics&minPrice=100&maxPrice=500&inStock=true
# Sıralama
GET /api/v1/products?sort=price&order=asc
GET /api/v1/products?sort=-createdAt,name # - prefix ile azalan sıra
# Alan seçimi (Sparse Fieldsets)
GET /api/v1/users?fields=id,name,email
# Arama
GET /api/v1/products?search=laptop
Kimlik Doğrulama ve Yetkilendirme
JWT (JSON Web Tokens)
JWT, durumsuz kimlik doğrulama için en yaygın kullanılan yöntemdir. Üç bölümden oluşur: header, payload ve signature. Token, Authorization başlığında Bearer şemasıyla gönderilir:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
JWT kullanırken dikkat edilmesi gerekenler:
- Token süresini kısa tutun (genellikle 15-60 dakika)
- Refresh token mekanizması kullanın
- Hassas bilgileri payload'a koymayın (token encode edilir, şifrelenmez)
- Güçlü bir imzalama algoritması kullanın (RS256 veya ES256)
- Token iptal mekanizması planlayın
OAuth 2.0
OAuth 2.0, üçüncü parti uygulamaların kullanıcı adına kaynaklara erişmesini sağlayan bir yetkilendirme çerçevesidir. Dört temel akış (grant type) sunar:
- Authorization Code: Web uygulamaları için en güvenli akış
- Client Credentials: Makine-makine iletişimi için
- Device Code: Klavyesiz cihazlar için
- PKCE (Proof Key for Code Exchange): Public client'lar (SPA, mobil) için güvenli akış
API Key
Basit senaryolar için API anahtarları kullanılabilir. Ancak API anahtarları, kullanıcı kimliği doğrulama amacıyla değil, istemci tanıma amacıyla kullanılmalıdır:
GET /api/v1/data
X-API-Key: abc123def456
Hata Yönetimi
Tutarlı ve bilgilendirici hata yanıtları, API'nin kullanılabilirliği için kritiktir. Standart bir hata yanıt formatı oluşturun:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "İstek doğrulama hatası.",
"details": [
{
"field": "email",
"message": "Geçerli bir e-posta adresi girilmelidir."
},
{
"field": "password",
"message": "Şifre en az 8 karakter olmalıdır."
}
],
"timestamp": "2026-03-14T10:30:00Z",
"path": "/api/v1/users",
"requestId": "req_abc123"
}
}
Hata yönetiminde en iyi uygulamalar:
- Her zaman uygun HTTP durum kodu kullanın
- Hata mesajlarını kullanıcı dostu ve açıklayıcı yapın
- Uygulama seviyesinde hata kodları tanımlayın
- Güvenlik bilgilerini (stack trace, veritabanı hataları) istemciye göstermeyin
- Her hataya benzersiz bir request ID atayın (loglama ve takip için)
- Doğrulama hatalarında hangi alanların sorunlu olduğunu belirtin
Dokümantasyon: Swagger ve OpenAPI
İyi bir API dokümantasyonu, API'nin benimsenmesi ve doğru kullanılması için vazgeçilmezdir. OpenAPI Specification (OAS), RESTful API'leri tanımlamak için endüstri standardıdır.
OpenAPI Specification
OpenAPI, API'nizin endpoint'lerini, parametrelerini, istek/yanıt şemalarını ve kimlik doğrulama yöntemlerini YAML veya JSON formatında tanımlamanızı sağlar:
openapi: 3.0.3
info:
title: Kullanıcı API
version: 1.0.0
paths:
/users:
get:
summary: Kullanıcıları listele
parameters:
- name: page
in: query
schema:
type: integer
default: 1
responses:
'200':
description: Başarılı
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
Swagger UI
Swagger UI, OpenAPI tanımınızdan otomatik olarak interaktif bir dokümantasyon arayüzü oluşturur. Geliştiriciler, doğrudan tarayıcıdan API'yi test edebilir. ASP.NET Core'da Swashbuckle veya NSwag, Node.js'te swagger-ui-express gibi araçlar ile kolayca entegre edilebilir.
Rate Limiting
Rate limiting, API'nin kötüye kullanımını ve aşırı yüklenmesini önlemek için kritik bir mekanizmadır. Yaygın rate limiting stratejileri:
- Fixed Window: Sabit zaman pencerelerinde istek sayısı sınırlama
- Sliding Window: Kayan zaman penceresiyle daha adil sınırlama
- Token Bucket: Token tabanlı, burst trafiğe izin veren yaklaşım
- Leaky Bucket: Sabit hızda istek işleme
Rate limit bilgilerini yanıt başlıklarında bildirmek en iyi uygulamadır:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1710410400
Retry-After: 60
HATEOAS: API Keşfedilebilirliği
HATEOAS (Hypermedia As The Engine Of Application State), REST'in en olgun seviyesidir (Richardson Maturity Model Level 3). Yanıtlarda, istemcinin bir sonraki adımda yapabileceği işlemleri bağlantılar aracılığıyla sunar:
{
"id": 123,
"name": "Ahmet Yılmaz",
"email": "[email protected]",
"_links": {
"self": { "href": "/api/v1/users/123" },
"orders": { "href": "/api/v1/users/123/orders" },
"update": { "href": "/api/v1/users/123", "method": "PUT" },
"delete": { "href": "/api/v1/users/123", "method": "DELETE" }
}
}
HATEOAS, API'nin keşfedilebilirliğini artırır ve istemcinin URL yapısına olan bağımlılığını azaltır. Ancak uygulanması ek karmaşıklık getirir ve tüm projeler için gerekli olmayabilir.
Güvenlik En İyi Uygulamaları
API güvenliği, uygulamanızın bütünlüğünü korumak için hayati önem taşır:
- HTTPS Kullanın: Tüm API trafiği şifrelenmiş olmalıdır. HTTP'yi asla üretim ortamında kullanmayın
- Input Validasyonu: Tüm gelen verileri sunucu tarafında doğrulayın. İstemci tarafı doğrulamaya güvenmeyin
- SQL Injection Koruması: Parametreli sorgular veya ORM kullanın
- CORS Yapılandırması: Yalnızca güvenilen origin'lere izin verin
- Rate Limiting: Brute force ve DDoS saldırılarına karşı koruma
- Hassas Veri Maskeleme: Şifre, kredi kartı gibi hassas verileri yanıtlarda döndürmeyin
- Content-Type Doğrulama: Beklenen Content-Type başlığını zorunlu kılın
- Güvenlik Başlıkları: X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security başlıklarını ekleyin
Önbellekleme (Caching)
Doğru önbellekleme stratejisi, API performansını önemli ölçüde artırır:
- Cache-Control Başlığı: Yanıtın ne kadar süre önbelleğe alınabileceğini belirtir
- ETag: Kaynağın değişip değişmediğini kontrol etmek için kullanılır. 304 Not Modified ile bant genişliği tasarrufu sağlar
- Last-Modified: Kaynağın son değişiklik tarihini bildirir
# Sunucu yanıtı
HTTP/1.1 200 OK
Cache-Control: max-age=3600
ETag: "abc123"
# İstemci tekrar sorgusu
GET /api/v1/products/1
If-None-Match: "abc123"
# Değişiklik yoksa
HTTP/1.1 304 Not Modified
API Tasarımında Yaygın Hatalar
RESTful API tasarlarken kaçınılması gereken yaygın hatalar:
- URL'lerde fiil kullanmak (
/getUsersyerine/users) - Tutarsız adlandırma (
/usersve/Productkarışımı) - Her şey için 200 OK döndürmek
- Hata detaylarını gizlemek veya aşırı detay vermek
- Versiyonlama yapmamak
- Sayfalama olmadan büyük veri setleri döndürmek
- PATCH yerine her zaman PUT kullanmak
- Güvenlik başlıklarını ihmal etmek
İyi bir API, bir kullanıcı arayüzü gibidir: kullanımı kolay olmalı, sezgisel çalışmalı ve hata durumlarında net geri bildirim vermelidir. API'nizi kendi istemciniz olarak düşünün ve "bu API'yi kullanmak ne kadar kolay?" sorusunu sürekli sorun.
Sonuç
RESTful API tasarımı, yazılım mühendisliğinin temel becerilerinden biridir. HTTP metotlarının doğru kullanımı, tutarlı URL yapısı, anlamlı durum kodları, güvenli kimlik doğrulama, kapsamlı hata yönetimi ve iyi dokümantasyon, profesyonel bir API'nin olmazsa olmazlarıdır. Bu rehberde ele aldığımız en iyi uygulamaları benimseyerek, hem geliştiriciler hem de son kullanıcılar için güvenilir, performanslı ve sürdürülebilir API'ler oluşturabilirsiniz. Unutmayın, en iyi API, kullanıcılarının en az sorun yaşadığı ve dokümantasyona en az başvurduğu API'dir.