RestApi ve HATEOAS kavramı

Bazı şeyler vardır, her yerde öyle kullanıldığını görürsünüz ve siz de farkında olmadan öyle kullanmaya başlarsınız. Bir gün alaylı olarak öğrendiğiniz bu şeyin adını duyar ve “ben hep öyle yapıyordum, onun bir adı mı varmış” dersiniz. İşte ben bugün o ‘bazı şeylerden’ birini yaşadım ve yaşadığım aydınlanmayı sizlerle de paylaşmak istedim. O şeyin adı “HATEOAS”, dokümantasyonlarda veya spesifikasyonlarda böyle böyle yapın diye öğrendiğimiz şeyin aslında bir adı varmış. 🙂

Bu yazıda konu hakkındaki Vikipedi makalesindeki örnekleri (1) geçmiş tecrübelerimle birleştirerek açıklayacağım.

Bu yazıyı daha önce yazdığım RESTFul Api Tasarım İncelikler yazı dizisine de ekledim. O dizideki yazılar da ilginizi çekebilir.

Nedir bu HATEOAS?

HATEOAS İngilizce “Hypermedia as the Engine of Application State” cümlesindeki kelimelerin baş harflerinden oluşturulmuş bir kısaltma ve REST API mimarisinin temel özelliklerinden biri. HATEOAS sayesinde istemciler bir REST API’yi nasıl tüketeceklerini bilmeden (veya asgari bilgiyle) o REST API’yi kullanabilirler. Az sonra basit bir örnekle bu ne demek daha iyi anlayacağız.

HATEOAS Örneği

Bir REST istemcisi ile bir REST uygulamasının herhangi bir uç noktasına istek gönderdiğimizde sonuç olarak beklediğimiz nedir? İlk aklımıza gelen tabii ki istediğimiz kaynakla ilgili bilgiler. Fakat iyi bir REST Api çoğu zaman bu kaynakla ilgili diğer kaynakların, yapılacak işlem ve alınabilecek bilgilerin listesini/bağlantılarını da gönderir.

Bir web sitesine girdiğinizde sayfada yapabileceğiniz işlemlerin linklerini açık bir şekilde görüp, “şuraya tıklarsam giriş yaparım”, “şuraya tıklarsam kategorileri görürüm”, “şuraya tıklarsam önceki sayfaya” giderim demeniz gibi, bir HATEOAS yapısına uygun bir RestApi’de istemciye hangi kaynakla ilgili ne yapabileceğini açıkça söyler.

BASİTLEŞTİRELİM

Böyle kavramsal cümleleri anlamak güç olabiliyor, o nedenle kısa bir örnekle basitleştirerek anlatıp, ardından Vikipedi’deki örneklere geçeceğim.

REST Api’mizden bir makalenin bilgilerini istedik. Gelen veri; “Makale Başlığı ve Makale İçeriği” olacaktır. Bununla birlikte “Yazar”, “Yorumlar”, “Kategoriler” vb. ilişkili kaynaklar olduğu ve bu kaynaklara ulaşılabilecek “URL” lerde gönderilecektir. Rest Client’ı “yazar”, “yorum”, “kategori” ne demek bilmek zorunda değildir. API’miz ilgili makalenin ilişkileri hakkında temel bilgiyi ve ayrıntılı bilgi alınacak adresi gönderir. Böylece istemci tarafında YORUMSAYISI>0’da yorum bağlantısını göster diye bir mantık kurmamız gerekmez.

VİKİPEDİ’DEKİ ÖRNEĞE GELİRSEK

Örneğin aşağıdaki örnek HESAP (ACCOUNT) kaynağından JSON şeklinde bilgi istiyor

GET /accounts/12345 HTTP/1.1
Host: bank.example.com
Accept: application/vnd.acme.account+json
...

Geri dönen temsili cevap ise şu;

HTTP/1.1 200 OK
Content-Type: application/vnd.acme.account+json
Content-Length: ...
{
    "account": {
        "account_number": 12345,
        "balance": {
            "currency": "usd",
            "value": 100.00
        },
        "links": {
            "deposit": "/accounts/12345/deposit",
            "withdraw": "/accounts/12345/withdraw",
            "transfer": "/accounts/12345/transfer",
            "close": "/accounts/12345/close"
        }
    }
}

Cevapta dönen bilgilere ek olarak; yatırma (deposit), çekme (withdraw), transfer(transfer) ve kapatma (close) bağlantıları var.

Daha sonra yapılan bir istekte hesap bakiyesinin eksiye düştüğü duruma bakalım;

HTTP/1.1 200 OK
 Content-Type: application/vnd.acme.account+json
 Content-Length: …
 {
     "account": {
         "account_number": 12345,
         "balance": {
             "currency": "usd",
             "value": -25.00
         },
         "links": {
             "deposit": "/accounts/12345/deposit"
         }
     }
 }

Bu durumda bağlantılar içinde çekme, transfer ve kapatma’nın yer almadığını sadece para yatırma bağlantısının olduğunu görüyoruz.

İstemci tarafında hesap bakiyesi 0’dan “büyükse şunu göster, değilse bunu gizle” vs. vs. bir mantık oluşturmamız da gerekmiyor.

Vikipedi’deki örneklerde ilişkilerden bahsedilmemiş ama çoğu zaman API servisi ilişkili kaynakların listesini ve o kaynaklarla ilgili bilgi alabileceğimiz url’leri de gönderir. Burada gösterilen sadece temel örnek, ana fikir aynı kalmak şartıyla daha kompleks API cevapları döndürülebilir.

HATEOAS bize ne sağlıyor?

HATEOAS bağlantı adresleri konusunda bağımlılıkları ortadan kaldırıp serbesti sağlıyor. RESTApi’yi kendimiz kullanalım diye değil, istemcilerin kullanması için yaptığımızı düşünürsek, bütün endpoint URL’lerinin istemci içine tanımlanması (hard code) hem zor, hem de teknik olarak doğru değil.

Her kaynakta, kullanılabilir bağlantıları cevap olarak döndürüldüğünde istemciden URL kodlaması yapılmadan, sadece metod isimlerine göre işlem yapılabilir. İstemcilere bir değişikliğe gitme gereği duymadan URL değiştirmek mümkün olduğu gibi, istemci bazında farklı URL’ler vermek bile mümkün olacaktır.

Son söz olarak; Herhangi bir API spesifikasyonuna uygun bir API tasarladığınızda muhtemelen zaten HATEOAS’a uygun olacak. Ancak kavramı, sağladıklarını ve nedeni bilmek yapıyı kafamızda daha rahat kurmamıza yardımcı olacaktır.

Sorularınız varsa veya fikir alışverişi yapmak isterseniz yorumlardan, Twitter , LinkedIn veya Instagram üzerinden ulaşabilirsiniz. Sayfanın sol alt köşesinde yer alan zil ikonuna tıklayarak tarayıcı bildirimlerine abone olabilir, yeni yazılardan haberdar olabilirsiniz. Sevgiler…

Referans

  1. Wikipedia contributors. HATEOAS. Wikipedia, The Free Encyclopedia. March 18, 2020, 00:21 UTC. Available at: https://en.wikipedia.org/w/index.php?title=HATEOAS&oldid=946088168. Accessed February 23, 2021.