Geçenlerde X’te gezinirken bir gönderiye denk geldim. Bir junior geliştiricinin tasarladığı iki endpoint paylaşılmıştı ve buradaki tasarım hatasının ne olduğu soruluyordu.
Endpoint’ler şunlardı:
GET /api/v1/followers/verified
GET /api/v1/followers/unverified
İlk bakışta çalışır gibi görünüyor. Hatta ne yapmak istediği de gayet anlaşılır: doğrulanmış takipçileri getir, doğrulanmamış takipçileri getir.
Ama API tasarımında mesele sadece “anlaşılıyor mu?” değil. Asıl mesele, doğru modellenmiş mi?
Buradaki problem şu: verified ve unverified, sanki followers altında ayrı birer kaynakmış gibi davranıyor. Oysa burada gerçek kaynak followers. verified ise bu kaynağın bir özelliği, yani filtreleme kriteri.
Daha temiz yaklaşım şu olurdu:
GET /api/v1/followers?verified=true
GET /api/v1/followers?verified=false
Burada ayrım çok daha net.
Path bize hangi kaynağa eriştiğimizi söylüyor: followers.
Query parametre ise bu kaynağı nasıl filtreleyeceğimizi söylüyor: verified=true veya verified=false.
Bence iyi API tasarımında en kritik ayrımlardan biri bu:
Path resource’u anlatır, query parametre filtreyi anlatır.
Bu ayrım küçük gibi görünüyor ama proje büyüdükçe ciddi fark yaratıyor.
Bugün sadece iki durum olabilir: verified ve unverified. Ama yarın işin içine pending, blocked, suspended, muted gibi başka durumlar da girebilir. Eğer her durumu ayrı endpoint olarak tasarlarsak API bir süre sonra şuna döner:
/followers/verified
/followers/unverified
/followers/pending
/followers/blocked
/followers/suspended
Bu yapı hem gereksiz endpoint kalabalığı oluşturur hem de aynı listeleme mantığını farklı route’lara dağıtır. Halbuki tek bir listeleme endpoint’i üzerinden bunu çok daha temiz yönetebiliriz:
GET /api/v1/followers?status=verified
GET /api/v1/followers?status=unverified
GET /api/v1/followers?status=pending
GET /api/v1/followers?status=blocked
Burada status kullanmak, özellikle ileride farklı durumlar eklenecekse daha esnek bir tercih olur. Eğer sistem gerçekten sadece doğrulanmış/doğrulanmamış bilgisinden ibaretse verified=true/false yeterli olabilir. Ama domain büyüyecekse status daha sağlıklı modelleme sağlar.
Bu örnek bana şunu tekrar hatırlattı: API tasarımı sadece route yazmak değil, aynı zamanda domain’i doğru okumak işi.
“Ben burada neyi kaynak olarak görüyorum, neyi filtre olarak görüyorum?” sorusunu doğru sormak gerekiyor.
Çünkü yanlış modelleme ilk başta çok sorun çıkarmayabilir. Endpoint çalışır, frontend veriyi alır, herkes yoluna devam eder. Ama birkaç ay sonra yeni filtreler, yeni durumlar, yeni listeleme ihtiyaçları geldikçe tasarımın zayıf tarafları ortaya çıkar.
Ben olsam bu örnekte endpoint’i şöyle tasarlardım:
GET /api/v1/followers?verified=true
veya daha geniş düşünüyorsam:
GET /api/v1/followers?status=verified
Aynı endpoint üzerine sayfalama, sıralama ve arama da rahatça eklenebilir:
GET /api/v1/followers?status=verified&page=2
GET /api/v1/followers?status=verified&sort=created_at
GET /api/v1/followers?status=verified&search=baris
Böylece hem endpoint sayısı artmaz hem de API’nin davranışı daha tahmin edilebilir olur.
Kısacası, /followers/verified çalışabilir ama iyi modellenmiş bir endpoint değildir. Çünkü verified burada ayrı bir kaynak değil, followers listesinin filtresidir.
Özetle:
Resource path’te durur. Filtre query parametrede durur.
Top comments (0)