RESTful API Nedir ve Standartları Nelerdir?

 

Başlamadan önce;
       Makale içerisinde API geliştirken kullanacağımız ve zamanla aşina olacağınız bazı terimler olacak. Bunları bazen alışkanlıktan bazen de Türkçeye çevirdiğinizde anlamı tam karşılamadığından ingilizce olarak kullanmış olabilirim. O yüzden o terimlere kısaca listeleyecek olursam;

URL: En basit şekilde tanımlayacak olursak, bir web sitesine erişirken kullandığımız adres diyebiliriz. Oluşturduğunuz API'ın da bir adresi olur ve bu adres üzerinden ona erişir, diğer servislerle bağlarsınız.

Endpoint: API üzerinde belirli bir amaç için oluşturulmuş metodunuza verilen isim. 
HTTP: Günümüz web teknolojisinde en yaygın kullanılan sunucu ve istemci arasındaki haberleşme protokolüdür. Genelde bir web sitesi üzerinde dolaşırken GET ve POST HTTP isteklerini yaygın olarak kullanırsınız fakat göreceksiniz ki API içerisinde farklı istek türleri de kullanılmakta.
İstek(HTTP Request); API üzerinde oluşturduğumuz çeşitli özellikteki endpoinlere, HTTP protokolü kullanarak yaptığınız taleplere denir.

  

RESTful API Nedir?

       API'ların ne olduğuna bu makalemizde anlatmıştık. Rest de temelinde HTTP protokolü üzerinden haberleşen bir mimari yaklaşımdır. Bu mimari yaklaşımı kullanan API'lara da Restful API olarak adlandırıyoruz. Restful standardı daha eski ve katı kuralları olan SOAP servislere bir çözüm olarak geliştirilmiş ve tercih edilmiştir.
       Birçok dilde kendi API'ınızı yazıp, yine dil bağı olmadan istediğiniz dilde yazılmış uygulamalar, web siteleri, başka servisler ile entegre edebilirsiniz.
       Restful olarak geliştirilmiş bir API üzerinden genellikle JSON tipinde dönüş yapılması tercih edilir fakat amaca ve isteğe göre XML, CSV, HTML veya düz bir metin olarak dönüş alabilirsiniz.

       Restul API üzerinde HTTP protokünde yer alan çeşitli tipleri(GET,PUT,POST,DELETE) de etkin bir şekilde kullanıyoruz. Bu şekilde anlamlı URL'ler oluşturup göze ve programcıya hoş gelen linkler kolaylıkla oluşturuyoruz.

 

RESTful URL Yapısı nasıl olmalı?

       Oluşturduğumuz url'leri başka bir yazılımcı, hatta bir analist baktığında kolayca anlayabilmelidir. Karmaşık isimlendirmeler ve url üzerine eklenecek gereksiz parametrelerden kaçınmalıyız. Örneğin aşağıdaki endpointi incelediğimizde;

GET https://api.caylakyazilimci.com/users/123

       GET isteği yaptığımızda "Users" içerisinde 123 id'li kayıtı getirmesini istiyoruz, aynı endpointe DELETE isteği yaparsak da 123 id'li kullanıcıyı siliyoruz.

       Kaynaklarda da yer verdiğim medium makalesi için bu konuyu özetleyen bir cümleye yer vermişler.

"The URL is a sentence, where resources are nouns and HTTP methods are verbs."
"URL'ler, HTTP metotlarının fiil ve kaynakların(controller ve sınıflarımız) isim olduğu cümlelerdir."

       Bu yüzden API üzerinde oluşturduğumuz URL'leri mümkün olduğunca bir cümle olarak düşünmeliyiz.

       HTTP istek türlerini ve kullanabilieceğimiz URL standartlarına makalenin devamında değineceğim. O yüzden makaleyi bitirdiğinizde nasıl bir URL oluşturmalıyım sorusuna cevabı kendiniz de veriyor olacaksınız.

 

URL Uzunluğu Ne Olmalı?

       Bir URL nasıl olmalı sorusuna verdiğimiz cevap okunur olmasıydı. Fakat fazla uzun url'ler de bir yerden sonra takip edilmesi zor bir hal alacaktır. Bunun için imkan oldukça kısa ve anlamlı tutulmalıdır.

       Yine de uç noktayı merak edenlerdenseniz, 2000 karakter altında tutacağınız URL'lerde bir sorun yaşamazsınız fakat 2000 karakter üzerindeki URL'lerde tüm cihazlarda ve browserlarda çalıştıramayabilirsiniz. Daha ayrıntılı bilgi için bu linkten faydalı bir stackoverflow konusuna(ingilizce) erişebilirsiniz.

 

Bir HTTP Request(isteği) nelerden oluşur?

       En yalın haliyle bir HTTP isteğini aşağıdaki bilgileri taşır;
       Request-Line: HTTP isteğin türü, hangi url'e yapılacağı ve http/https protokolü bilgisi
       Header: Yapılan isteği niteleyen ve isteğe ait temel bilgileri içeren parametreleri taşır. Gönderilmesi zorunlu değildir, bir ve birden fazla header parametresi gönderebiliriz.
       Body: Eğer POST,PUT,PATCH gibi API üzerinden bazı kayıt ve işlemler yapılmasını istiyorsak, bu bilgileri de isteğimizin Body alanında göndeririz. Restful bir API'da JSON olarak bu bilgileri gönderilmesi tercih edilir.
       Kullandığınız bowser'ın geliştici seçenekleri(F12) içerisinde Network tab'I altında arkaplanda yapılan istekleri inceleyebilirsiniz. Örneğin bu siteye girerken yaptığınız bir anasayfa isteği aşağıdaki gibidir;

 

HTTP Request(istek) Türleri Neler?

       Biz bir adrese istek yaparken o isteğin türünü de belirtiriz. Örneğin browser üzerinden bir web sitesine gittiğinizde, o adrese erişmek istediğimizi browser'ımız karşı sunucuya GET(getir) isteği yaparak belirtir ve kaynak sunucu bize o sitenin html cevabıyla dönüş yapar. Bir üyelik formu doldururken kaydet dediğinizde browser'ınız kaynak sunucuya sizin girdiğiniz bilgiler ile beraber bir POST(gönder, postala) isteği yapar.
       API'larımızda hem anlamlı URL'ler oluşturmak hem de karmaşıklığı daha aza indirmek için yaygın kullanılan HTTP istek türleri olarak aşağıdakileri sayabilirim;

GET: Veri çekmek için kullanılır.

POST:Yeni bir kayıt oluşturmak için kullanılır.

PUT: Varolan bir kayıtı güncellemek için kullanılır.

PATCH: Varolan bir kayıtta belirli bir parça üzerinde güncelleme yapılacaksa kullanılabilir. Bu işlem istek yerine tüm güncellemeler için PUT kullanımı da yaygındır.

DELETE: Varolan bir kayıtı silmek için kullanılır.

 

Header Nedir?

       Yaptığımız isteğe ait temel bilgileri de sunucuya iletmemiz gerekebilir. Bu isteği yaptığımız sunucu bu isteği açmadan önce Header içerisinde yer alan bilgileri işleyip ona göre iç akışına devam eder. Örneğin dil(culture) bilgisini header üzerinde taşıyıp sunucunun bizim isteğimizi işlerken hangi dile göre hareket edeceğini bilmesini sağlarız. Bir diğer örnek olarak sadece üye olan kullanıcıların erişebildiği bir API yapmış ve yetkisi olmayan kişilerin istek yapmasını engellemek isteriz. Bunun için de yaptığımız isteklerde Authentication parametresiyle beraber anahtar bilgisini(token) sunucuya iletip önce bu bilgiyi kontrol etmesini ve sadece yetkisi olmayan kişilerin API içerisine erişebilmesini sağlarız.
       Header için kullanılan standart parametreler vardır. Culture, Content-Type, Authentication bunlardan bazılarıdır. Bunları göndermemiz zorunlu değildir ama iyi bir API için ihtiyacınız olacaktır.

       Header üzerinde kullanılan standartları buradan detaylı bir şekilde inceyelebilirsiniz. 
       Ayrıca bu listedekiler dışında kendi istediğiniz isimde bir header adı oluşturup onu da sunucuya yaptığınız istekte gönderebilirsiniz. Bunu yaparken sunucunun da bu header değerini aynı isimde aldığından emin olmanız gerekmektedir.


JSON nedir?

       JSON günümüzde sunucular arasında haberleşme yapmak ve aynı zamanda ufak boyutta taşınabilmesinden ötürü oluşturulmuştur. XML standardına alternatif olarak oluşturulmuştur. Düzenli veri saklamak için de JSON formatında dosyalar oluşturulup burada anlamlı modeller oluşturulabilir.
       JSON içerisinde bir anahtar(key) ve o anahtara ait değer(value) içerir.

       JSON yapıları ile ilgili daha ayrıntılı bilgi için bakabilirsiniz(1, 2)


       Elimden geldiğince Türkçe kelimeler kullanmaya çalıştım fakat kullandığımız URL yapısında ingilizce isimlendirmeler tercih edilmeli. URL'de kullanacağınız türkçe karakterlerde çeşitli uyum sorunları yaşayabilirsiniz. Bu yüzden ben de makalenin geri kalanında anlatacağım URL formatında Users (Kullanıcılar) endpointi üzerinden ilerleyeceğim.

 

Restful API Standartları Neler?

       Burada sıralayacağım maddeler zorunlu kurallar değildir fakat bir Restful API geliştirilirken uyulması tercih edilen, kabul görmüş kalıplardır;
       1. Bir API yaparken aynı sınıfa ait işlemleri bir grup altına toplamalıyız. Örneğin API üzerinden kullanıcılara ait erişmek ve işlem yapmak istediğimizde hepsini "Users" url'i üzerinden yapmalıyız.
       2. Bir sınıfı temsil eden veya belirli bir amaç için grupladığımız bu endpointleri, çoğul isimle oluşturmalıyız.
       Örneğin;

api.caylakyazilimci.com/company yerine api.caylakyazilimci.com/companies
api.caylakyazilimci.com/user yerine api.caylakyazilimci.com/users 

       olarak isimlendirmeyi yapmalıyız.
       3. Oluşturduğumuz endpointin doğrudan kendisine atacağımız GET isteklerinde o sınıfa ait tüm listeyi dönmeliyiz.
       Örneğin;

api.caylakyazilimci.com/users 
api.caylakyazilimci.com/companies

       4. Bir sınıfa ait tek bir kayıta ulaşmak istediğimizde onun ait olduğu sınıfa, onu temsil eden benzersiz(unique) id değeri ile istek atmalıyız ve karşılığında bize o sınıfa ait bilgileri dönmeliyiz.
       Örneğin;

api.caylakyazilimci.com/users /1
api.caylakyazilimci.com/users /CFAF1A94-91D6-4413-9320-7DD7157A2E54

       5. Bir sınıfa ait yeni bir kayıt oluşturmak istediğmizde doğrudan onun sınıfına POST isteği ile beraber body içerisinde bu yeni bilgileri göndermeliyiz.
       Örneğin;

api.caylakyazilimci.com/users 

       6. Bir sınıfa ait kayıtı silmek istediğimizde, ona ait id değeri ile DELETE isteği attığımızda silmeliyiz.
       Örneğin;

api.caylakyazilimci.com/users /5
api.caylakyazilimci.com/users /CFAF1A94-91D6-4413-9320-7DD7157A2E54

       7. Bir sınıfa ait kayıtta, ona bağlı diğer sınıflara erişmek istediğinizde, yani bir Users altında User kayıtının bildirimlerine(notifications) ulaşmak istediğinizde aşağıdakine benzer sıralı bir URL altında dönebilirsiniz.

api.caylakyazilimci.com/users /2/notifications

       Böylelikle url'e baktığınızda kolayca ne iş yaptığını anlayabiliyorsunuz.
kullanıcılardan -> 2 id'li kullanıcının -> bildirimlerini GET(getir)



Buraya kadar bir isteği nasıl yapacağımızı öğrendik. Şimdi sıra talepte bulunan istemcilere(client) cevabı vermekte.

HTTP Response(cevap) nelerden oluşur?

       Her HTTP Request'in bir yapısı olduğu gibi, döndüğümüz cevabın da belirli bir yapısı vardır. İstekte bulunan kullanıcılar sunucudan yanıtını aldığında bu cevap üzerindeki parametrelerden kendi aksiyonlarını alabilir. Basit bir haliyle bir HTTP Response aşağıdaki yapıdan oluşur;
Status-line; kendi içerisinde HTTP protokolü, http status kodu ve status mesajı yer alır. Örneğin;"HTTP/1.1 404 Not Found"
Header; Gönderdiğimiz HTTP Requestin header bilgisi olduğu gibi bize dönen cevabın da header'I olabilir.
Body; Tüm isteklerde olmasa da bir model almak istediğmizde veya sunucudan bir cevap bekledğimizde buradn talep ettiğimiz veriye ulaşırız. API'da dönen JSON modeli buradan okuruz.

 

HTTP Status(durum) Kodları Nelerdir?

       Yaptığımız isteğin karşılığında sunucu bu isteğimizi işlemeden önce bir takım kontrollerden geçirir, ardından isteği işler ve cevabı döner.
Bu süreç boyunca çeşitli hatalar oluşabilir veya geçerli olmayan istekleri istekte bulunan adrese bildirmek gerekir. Örneğin; kullanıcı login mi, yetkisi var mı, culture bilgisi bizim için geçerli mi, böyle bir url var mı, gönderilen parametreler benim için geçerli mi sunucuda yapılan kontrollerden bazılarıdır.
       Karşılıklı olan bu iletişimi kolaylaştırmak ve sunucuda olan bu işlemleri belirten çeşitli kodlar(status codes) vardır.
       Bu hata kodları kendi içerisinde 5 grup ile incelenir. 3 basamaklı sayılardan oluşur, ilk basamağı cevabın türünü tanımlarken diğer iki basamak da cevaba ait detayı belirtir. Buna en bilinen örnek olarak varolmayan bir sayfaya gitmek istediğimizde karşımıza çıkan "404 Sayfa Bulunamadı" hatasını verebiliriz.

HTTP Hata Kodları

• 1xx – Bilgi Mesajları
       İsteğin alındığıyla alakalı bilgiler döner, fakat api haberleşmesinde pek kullanılmaz.

• 2xx – Başarılı Mesajları
       İsteğin sunucu tarafından sorunsuz işlenip, tamamlandığını belirtir.
       Sık kullanılan 2xx'li kodlar;
       • 200 OK - İsteğin sorunsuz işlendiğini belirtir. Karşılığında bir cevap bekleniyorsa BODY içerisinde yer alır.
       • 201 CREATED - POST isteklerinin yanıtı olarak dönülmesi tercih edilir. Oluşturulması istenen kayıtın sorunsuz oluştuğunu belirtir. BODY içerisinde oluşan kayıta ait modeli veya ID değeri dönülebilir.
       • 204 NO CONTENT - İsteğin sorunsuz tamamlandığını belirtir. BODY içerisinde herhangi bir dönüş olmaz. Genellikle dönüş beklenmeyen isteklerde kullanılır. Örneğin DELETE isteği yaptığınızda 204 dönebilirsiniz. Bu silme isteğinizin tamamlandığını belirtir.
• 3xx – Yönlendirme Mesajları
       İsteğiniz sunucuya giderken bir problem yaşadığını belirtir.
       Sık kullanılan 3xx'li kodlar;
       • 301 MOVED PERMANENTLY: İstek yaptığımız adresin kalıcı olarak başka bir adrese taşındığını belirtir.
       • 307 MOVED TEMPORARY: İstek yaptığımız adresin geçici olarak başka bir adrese taşıntığını belirtir.
• 4xx – Client(istekte bulunan cihaz/kişi) Hata Mesajları
       Gönderdiğimiz isteğin bizim kabul şartlarımızı sağlamadını ve daha fazla devam edemeyeceğini belirtir.
       Sık kullanılan 4xx'li kodlar;
       • 400 BAD REQUEST: Gönderilen parametreler kabul şartlarını taşımadığında dönülür. Örneğin sayı aldığınız bir alana metin göndermeye çalıştığınızda bu değerleri kontrol edip uygun olmadığını döner.
       • 401 UNAUTHORIZED: İsteği yapmaya yetkisi olmadığını beliritir.
       • 404 NOT FOUND: İstek yapılan adresin olmadığını belirtir.
       • 405 METHOD NOT ALLOWED: Adrese yapılan HTTP request türünün bu url için geçerli olmadığını belirtir. Örneğin POST istekleri kabul eden bir adrese GET isteği yapıldığında bu hatayı alabilirsiniz.
       • 408 REQUEST TIMEOUT: Yapılan isteğin sunucu tarafından kabul edilen maksimum süreyi aştığını ve izin verilen sürede yanıtın dönülemediğini belirtir.
• 5xx – Sunucu(server) Hata Mesajları
       Biz yazılımcıları en üzen hata kodlarıdır. Sunucu ve kod kaynaklı oluşan hatalarda bu kodlarla dönüş yapılır.
       Sık kullanılan 5xx'li kodlar;
       • 500 INTERNAL SERVER ERROR: isteğin işlenmeye başladığını, fakat işlenirken bir hata oluştuğunu ve yarıda kesildiğini belirtir. Ardından telefonunuz da çalar zaten.
       • 503 SERVICE UNAVAILABLE: İstek yapılan yerde bir şey var, ama bir o kadar da yok. İstek yapılan API durmuş veya çökmüş. Nam-ı diğer; "Baba akü yok!" mesajı.

Versiyonlama

       Bir API yazdığınız ve onu kullanan başka uygulamalar geliştirdiniz, yeni müşterilerle anlaştınız ve onlar sizin aldığınız parametreler ve döndüğünüz cevaplara göre kendi uygulamalarını geliştirdiler. Her şey dört dörtlük çalışıyor. Günlerden bir gün en çok istek alan endpointlerinizden birinde kökten bir değişiklik yapmanız gerekti. Bunu mevcut adresinizde yapmanız, bir sürü hata, susmayan telefonlar ve kabaran hata loglarına neden olacaktır.
       Oluşturduğumuz API'larda versiyonlama kullanarak ilgili endpointin eski ve yeni versiyonlarını ayakta tutabilir, kullanıcılarınıza ve müşterilerinize bu geçişi daha yumuşak yaptırabilirsiniz.
       Versiyon bilgisini genellikle API adresinizin peşinden direkt URL üzerinden belirtilmesi tercih edilir. Örnek olarak kullanıcıları dönen endpointimizi iki farklı versiyon üzerinde yayınladığımızı düşünürsek aşağıdaki gibi bir URL olması beklenir;

GET https://api.caylakyazilimci.com/v1/users/111222333
GET https://api.caylakyazilimci.com/v2/users/111222333

       Bu sayede 2 farklı versiyonda API isteklerinizi karşılayabilirsiniz.

 

Birçok geliştirici tarafından kullanılan örnek API dökümantasyonlarına bakarak gelişmiş bir API nasıl olmalı, nelere dikkat ediyorlar, hangi standartlara uyuyorlar inceleyebilirsiniz. Popüler API'lara bazı örnekler;
Github: https://developer.github.com/v3/
Twitter: https://developer.twitter.com/en/docs/api-reference-index
Facebook: https://developers.facebook.com/docs/graph-api/reference
Instagram: https://www.instagram.com/developer/endpoints/
Çeşitli özelliklerde ve eğlencesine yapılmış çeşitli API'ların olduğu bir liste: https://apilist.fun/

 

Aklınıza takılan soruları mesaj yoluyla veya iletişim alanından sorabilirsiniz. Gözünüze çarpan eksik/ hatalı alanları söyleyebilir, eklemek istediklerinizi paylaşabilirsiniz. 

Kaynak olarak kullandığım linkler;
https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md
https://medium.com/hackernoon/restful-api-designing-guidelines-the-best-practices-60e1d954e7c9
https://www.tutorialspoint.com/http/http_requests.htm
https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages

 

 

 

Add comment