API Tasarımı & REST Mimarisi 3 dk okuma 7 okunma

REST'te Kaynak Modelleme ve İlişkileri Tasarımı

REST'te kaynak modelleme, iş alanındaki varlıkları URI ile temsil edilebilir kaynaklara dönüştürmektir. Doğru modelleme; çoğul isimlendirme, fiilsiz URI'ler, hiyerarşi derinliğinin sınırlanması ve ilişkilerin (bire-bir, bire-çok, çoka-çok) tutarlı tasarlanmasına dayanır. Alt kaynak (nested) ile filtrelenmiş üst düzey kaynak arasındaki denge, API'nin kullanılabilirliğini ve bakımını belirler.

REST'te Kaynak Modelleme ve İlişkileri Tasarımı

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/123 yanı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/categories ve /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.

Tüm yazılar Soru ya da yorumun mu var? Yaz