Bu yazı, adresinde yer alan yazının Türkçe'ye çevrilmiş ve bazı küçük eklemeler yapılmış halidir.
Adım Adım RESTful API Tasarımı
Yazılım geliştiriciler olarak, hayatımızın hemen hemen her günü REST API’ler geliştiriyor ya da kullanıyoruz. API’nin en genel anlamı, sistemlerin birbirleriyle haberleşebilmesidir. Amazon, API’lerin iletişim için efektif şekilde kullanılması konusunda en iyi örnektir.
Bu makale boyunca, sıklıkla yapılan hatalardan kaçınarak nasıl daha iyi RESTful API’ler tasarlanabileceği hakkında konuşacağız.
Jeff Bezos’un “Başarının Anahtarı” Talimatı
Bazılarınız, Jeff Bezos’un Amazon geliştiricilerine yönelttiği talimatları biliyordur. Eğer henüz bunları duyma şansına sahip olmadıysanız, aşağıdaki özet bu durumun özeti niteliğinde olacaktır.
-
Tüm geliştirici takımları, verileri ve fonksiyonaliteleri servis arayüzleri aracılığıyla ortaya koymalıdır.
-
Takımlar, mutlaka bu arayüzler aracılığıyla birbiriyle haberleşmelidir.
-
Direkt olarak bağlantı kurma, başka bir ekibin veri kaynağını direkt olarak okuma, paylaşılabilir-bellek gibi yapılarla verinin paylaştırılması, herhangi bir arka-kapı (back-door) gibi iletişim süreçlerine kesinlikle izin verilmeyecek. İzin verilen tek iletişim, ağ üzerinden yapılan servis arayüzü çağrılarıdır.
-
Hangi teknolojinin kullanıldığı hiçbir önem arz etmez. HTTP, Corba, Pubsub gibi özel protokoller de buna dahildir. Bezos, kesinlikle bununla ilgilenmez.
-
İstisnasız tüm servis arayüzleri ilk geliştirme aşamasından başlayarak dış dünya tarafından kullanılabilir olarak tasarlanmalıdır. Bir başka deyişle, geliştirici ekibi yazılım dizaynının diğer geliştiricilerin de göreceği şekilde planlamalıdır.
-
Bu talimatları yerine getirmeyen her kimse, kovulacaktır.
Günün sonunda bu talimatlar, Amazon’un başarısının anahtarı oldu. Amazon’un AWS gibi ölçeklenebilir sistemler ve hizmetler sunabilmesi sağlandı.
RESTful API Tasarım Prensipleri
Basit tut!
Servis arayüz URL’lerinin mümkün olduğunca basit tutulması gereklidir. Örneğin, ürün için bir endpoint geliştiriliyorsa şu şekilde dizayn edilmelidir:
/products
/products/12345
İlk endpoint tüm ürünleri listelerken, ikinci endpoint, özel bir ürünü listelemek için kullanılır.
Fiil değil isim kullan!
Geliştiriciler tarafından yapılan en büyük hatadır. Genellikle, API’leri tanımlamak için URL’lerde eylemler kullanılır ancak bu iş için HTTP metotlarının olduğu unutulur. Örneğin tüm ürünleri listelemek için
/products
URL’i kullanılmalıdır. Şu ise hatalı yöntemdir:
/getAllProducts
Doğru http metotlarını kullan!
RESTful API operasyonlarının gerçekleştirilmesi ve tanımlanması için fazlaca metot hizmet edebilir duurmdadır.
-
GET: Kaynak veriyi ya da verileri getirmek için kullanılır.
-
POST: Yeni bir kaynak veri ya da veri dizisi oluşturmak için kullanılır.
-
PUT/PATCH: Varolan bir kaynak ya da kaynak dizisini güncellemek için kullanılır.
-
DELETE: Varolan bir kaynak ya da kaynak dizisini silmek için kullanılır.
Her operasyon için doğru metodu seçmek oldukça önemlidir!
Çoğul kullan!
Bu konu oldukça tartışmalı. Bazı insanları kaynak URL’lerini tekil oluştururken bazıları ise çoğul kullanmayı tercih eder. Örneğin;
/products
/product
Ben, tekil bir kaynak mı yoksa bir kaynak dizisi mi istediğim konusunda tereddüt yaşamamak adına çoğul kullanmayı tercih ediyor. Böylece bir dizi talebinde bulunduğumda URL’e /product/all gibi bir ifade eklentisi yapmak durumunda kalmıyorum.
Bazı insanlar bu durumu kabullenmeyebilir ancak benim önerim proje boyunca aynı şekilde kullanmaktır.
Parametre kullan!
Bazı durumlarda API endpoint’lerine ID’den farklı olarak birden fazla detay geçmek gerekebilir. Bunun için API tasarımında sorgu parametreleri kullanmalıyız.
-
/getProductsByNameyerine/products/?name=’ABC’ -
/getProductsByTypeyerine/products/?type=’123’
Böylece, tasarımda basitlik sayesinde uzunca URL’ler oluşturmaktan kurtulabilirsiniz.
Doğru HTTP durum kodlarını kullan!
Kullanabilecek bol miktar HTTP kodu mevcuttur! Çoğumuz sadece 2 tanesini – 200 ve 500 – kullanıyoruz. Bu kesinlikle doğru bir yöntem değil. Aşağıda, bazı sık kullanılan HTTP durum kodları verilmektedir:
-
200 OK: En sık kullanılan HTTP durum kodudur ve operasyonun başarıyla gerçekleştiğini ifade eder.
-
201 CREATED: POST metodu ile oluşturulmak istenen içeriğin başarıyla oluşturulduğunu ifade eder.
-
202 ACCEPTED: İsteğin sunucuya başarıyla iletildiğini ifade eder.
-
400 BAD REQUEST: İstemci tarafından gönderilen isteğin doğrulanması esnasında oluşan hata durumunu ifade eder.
-
401 UNAUTHORIZED / 403 FORBIDDEN: İsteği yapan kişinin bu operasyonu gerçekleştirmek için gerekli yetkisi olmadığını ifade eder.
-
404 NOT FOUND: İstenilen içeriğin sistemde yer almadığını ifade eder.
-
405 METHOD NOT ALLOWED: İstek yapmak için kullanılan HTTP metodunun bu operasyon için geçerli olmadığını ifade eder.
-
414 REQUEST-URI TOO LONG: İstek yapılan URL’in çok uzun olduğunu ifade eder.
-
500 INTERNAL SERVER ERROR: Kesinlikle direkt olarak atılmamalıdır. Sistemde bir hata oluşması durumunu ifade eder.
-
502 BAD GATEWAY: İstek yapılan sunucunun, isteği orijinal sunucuya ilettikten sonra aldığı cevabın geçersiz bir cevap olduğunu ifade eder.
Versiyonla!
API versiyonlama oldukça önemli bir konudur. Bir çok farklı şirket, bir çok farklı yöntem kullanmaktadır. Bazıları bunun için tarih kullanırken, bazıları ise versiyonu sorgu parametresi olarak kabul eder. Genellikle kaynağın başına eklenerek kullanımı tercih edilir. Örneğin;
/v1/products
/v2/products
/v1.2/products gibi kullanımlardan kaçınmayı tercih ediyorum çünkü bu, API’nın sıklıkla değiştiğine işaret eder. Ayrıca nokta işareti URL’de açıkça görünmeyebilir. Dolayısıyla basit tutulmalıdır.
Diğer bir best-practice ise API versiyonu değiştiğinde, geçmişe uyumluluğun göz önünde tutulmasıdır. Böylece API tüketicilerine, yeni versiyona uyumluluk için yeterli vakit sağlanmış olur.
Sayfalama kullan!
Sayfalama kullanılması, API fonksiyonunun devasa veriler döndürmesini engeller. Eğer yük dengeleme doğru bir şekilde tasarlanmadıysa bu devasa veriler sayesinde tüketici, sunucularınızı aşağı indirebilir! Aklımızda tutmamız gereken en önemli konu, API tasarımı yanlış kullanıma kapalı olacak kadar basit ve anlaşılması kolay olmalıdır.
Önerdiğim anahtar kelimeler limit ve offset. /products?limit=25&offset=50 (50’inci kayıttan başlayarak 25 kayıt getir!) ifadesi bir örnektir. Ayrıca varsayılan limit ve offset tanımlamalarının olması da önemlidir.
Çıktı formatları
Günümüz dünyasında bir çok uygulama JSON sonuç seti dönmektedir ancak eski tip uygulamalar hala XML tipinde çıktıya da ihtiyaç duyabilir.
Uygun hata mesajlarını kullan!
İstek sonucu oluşan bir hatayı, kullanıcıya uygun bir ID ve hata mesajı ile göndermek her zaman doğru bir yötemdir. Örneğin Facebook Graph API kullamnıyorsanız, hata durumunda şöyle bir mesajla karşılaşırsınız:
{
"error": {
"message": "(#803) Some of the aliases you requested do not exist: products",
"type": "OAuthException",
"code": 803,
"fbtrace_id": "FOXX2AhLh80"
}
}
Ayrıca hata mesajını içeren URL’ler döndüren ve bu URL’ler içerisinde kullanıcıyı, hata ile nasıl baş etmesi gerektiği konusunda yönlendirmen hata mesajları da gördüm.
OpenAPI yönlendirmelerini kullan!
Swagger gibi uygulamalar ile şirketinizdeki tüm ekiplerin belirli prensiplere uyulmasını sağlamak faydalı olabilir.
Sonuç
Daha iyi bir iletişim kurmak için API tasarımlarının önemi oldukça açıktır ve kötü bir tasarım, karışıklığı arttırabilir. Bu durumda, iyi tasarlamak için elinden geleni yap ve gerisini sadece implementasyona bırak!