REST'te Kaynak Modelleme ve İlişkileri Tasarımı
REST mimarisinin merkezinde kaynaklar (resources) vardır. Bir kaynak; bir varlığı, bir koleksiyonu veya bir hizmeti temsil eder ve HTTP metotlarıyla üzerinde işlem yapılabilir. API'nizin başarısı, büyük ölçüde kaynakları ne kadar doğru modellediğinize ve aralarındaki ilişkileri ne kadar tutarlı tasarladığınıza bağlıdır.
1. Kaynak Türleri
| Tür | Açıklama | Örnek |
|---|---|---|
| Koleksiyon | Birden fazla öğe içeren kaynak | /api/products |
| Öğe (Item) | Koleksiyon içindeki tek bir öğe | /api/products/123 |
| Tekil (Singleton) | Yalnızca bir örneği olan kaynak | /api/profile |
| Alt Kaynak | Başka bir kaynağa bağlı kaynak | /api/users/123/orders |
2. Kaynak İsimlendirme Kuralları
A. Çoğul İsimler Kullanın
Koleksiyonlar her zaman çoğul olmalıdır: /api/users, /api/products. Tekil kullanım (/api/user) tutarsızlık yaratır.
B. Fiil Değil, İsim Kullanın
URI kaynağı tanımlar; eylemi HTTP metodu belirler.
text
✅ GET /api/users/123 ✅ POST /api/users ✅ DELETE /api/users/123 ❌ GET /api/getUser?id=123 ❌ POST /api/createUser ❌ POST /api/deleteUser/123
C. Küçük Harf ve Tire Kullanın
/api/order-items doğru; /api/OrderItems veya /api/order_items yanlıştır.
D. Dosya Uzantısı Kullanmayın
Format, Accept başlığı ile belirtilir; URI'de .json gibi uzantı olmaz.
3. İlişki Türleri ve Tasarım Kararları
A. Bire-Bir İlişki (Örn. User → Profile)
İki yaklaşım vardır:
-
Alt kaynak:
/api/users/123/profile -
Genişletilmiş temsil:
/api/users/123yanıtında profil bilgisi de döner.
Profil, kullanıcıdan bağımsız düşünülemiyorsa alt kaynak; ayrı bir yaşam döngüsü varsa üst düzey kaynak tercih edilir.
B. Bire-Çok İlişki (Örn. User → Orders)
-
Alt kaynak:
/api/users/123/orders -
Filtrelenmiş üst düzey kaynak:
/api/orders?userId=123
Karar Kriteri: Sipariş, kullanıcıya bağımlı mı? Eğer sipariş bağımsız bir varlık olarak da anlamlıysa (ör. sipariş numarasıyla doğrudan erişim gerekiyorsa), üst düzey kaynak + filtre daha esnektir.
C. Çoka-Çok İlişki (Örn. Product ↔ Category)
-
Ayrı ilişki kaynağı:
/api/product-categories?productId=123 -
Her iki taraftan erişim:
/api/products/123/categoriesve/api/categories/456/products
İlişkiye ait ek veri varsa (ör. priority, createdAt), ara kaynak modellemek daha temizdir.
4. Hiyerarşi Derinliği: Ne Kadar İç İçe?
Kabul edilebilir (2-3 seviye):
text
/api/users/123/orders /api/users/123/orders/456
Kaçınılması gereken (4+ seviye):
text
/api/users/123/orders/456/items/789/reviews
İlke: Bir kaynak, üst kaynağa bağımlı olmadan da anlamlıysa, onu üst düzey kaynak yapın. Örneğin, sipariş kalemi (order-item) kendi kimliğiyle erişilebilir olmalıdır: /api/order-items/789.
5. İlişkili Veriyi Sunma Stratejileri
A. Minimal Temsil (Reference by ID)
json
{ "id": 456, "total": 250.00, "customerId": 123 }
Küçük payload; ancak istemci ek çağrı yapmak zorunda kalır.
B. Genişletilmiş Temsil (Embedded)
json
{ "id": 456, "total": 250.00, "customer": { "id": 123, "name": "Ahmet" } }
Tek çağrıda tüm veri; ancak payload büyür ve veri tekrarı oluşur.
C. Hibrit: expand Parametresi (Önerilen)
text
GET /api/orders/456 → Minimal GET /api/orders/456?expand=customer → Genişletilmiş
İstemciye seçim hakkı tanır; hem esneklik hem performans dengesi sağlar.
Güvenlik Uyarısı: expand parametresini beyaz liste ile doğrulayın. Aksi halde kötü niyetli bir istemci, çok derin iç içe yüklemelerle sunucuyu çökertebilir (DoS).
6. HATEOAS ile İlişki Keşfi
İlişkili kaynakların bağlantılarını yanıta eklemek, istemcinin API'yi keşfetmesini sağlar:
json
{
"id": 456,
"total": 250.00,
"links": [
{ "rel": "self", "href": "/api/orders/456", "method": "GET" },
{ "rel": "customer", "href": "/api/users/123", "method": "GET" },
{ "rel": "items", "href": "/api/orders/456/items", "method": "GET" },
{ "rel": "cancel", "href": "/api/orders/456/cancel", "method": "POST" }
]
}
7. Sık Yapılan Hatalar
| Hata | Sonuç | Çözüm |
|---|---|---|
| Fiilli URI'ler | REST dışı, tutarsız | Sadece isim; eylem HTTP metodunda |
| Aşırı derin iç içe yapı | Kırılgan, okunaksız | Maksimum 2-3 seviye |
| Tutarsız isimlendirme | Öğrenme eğrisi artar | Çoğul, küçük harf, tire |
| Her ilişki için alt kaynak | URI karmaşası | Bağımsız kaynakları üst düzeye taşı |
| İstemciye aşırı veri yükleme | Gereksiz payload | Minimal + expand hibrit |
Sonuç
REST'te kaynak modelleme, bir veritabanı şemasının HTTP üzerinden yansıması değil, iş alanının doğal bir temsilidir. Tutarlı isimlendirme, doğru ilişki tasarımı, sınırlı hiyerarşi derinliği ve istemciye esneklik sunan expand mekanizması, bakımı kolay ve kullanılabilir bir API'nin temelini oluşturur. Unutmayın: İyi bir kaynak modellemesi, API'nizin hem bugününü hem de yarınını şekillendirir; yanlış bir model, sonradan düzeltilmesi en pahalı karardır.