geri

Play! Framework ile asenkron HTTP

23/03/2012

Geçtiğimiz hafta içerisinde Play! Framework Türkiye Google Grubu'nda güzel bir tartışma konusu oldu. Ahmet Alp Balkan'ın başlattığı tartışmaya Erdem Ağaoğlu'nun yazdığı mail damga vurdu:) Aynı tartışmada konuyla ilgili uzun boylu bir yazı yazacağıma söz vermiştim. Bu yazıda, söz verdiğim konulara değinmeden Play! Framework ile asenkron işlerin nasıl yapıldığını örneklemeye çalışacağım. Söz vermiş olduğum 'Neden non-blocking IO, neden Tomcat "eski teknoloji", neden Java ile ancak bu kadar' konularına ise daha fazla zaman ayırarak ileriki bir zamanda değinmeyi düşünüyorum.

Anlatmaya çalışacağım örnek iki ayrı uygulamadan oluşmakta. İlk uygulama bir REST API sağlayıcı olmakla birlikte kullanıcı oluşturan ve kullanıcı ayrıntılarını döndüren iki API sağlıyor olacak. Diğer uygulama ise ilk uygulamanın sağladığı API'leri kullanacak. İlk uygulamaya "Provider", ikinci uygulamaya "Client" diyeceğim.

Önce Provider içinde kullanıcıları saklamak üzere User modelini oluşturarak işe başlayalım. Sonrasında kullanıcı oluşturmaya ve istenilen kullanıcının ayrıntılarını döndürmeye yarayan API fonksiyonlarını yazalım. Bu fonksiyonlar Provider uygulamasında Provider controller'ı içinde yer alsınlar. routes dosyasını güncelleyerek yazdığımız API'ler için HTTP route'ları belirleyelim.
GET     /api/user                               Provider.getUser
POST    /api/user                               Provider.createUser
Dikkat edeceğiniz üzere iki API için de aynı route'u kullanacağız. Hangi API'ye ulaşmak istendiği ayrımını HTTP metodu(GET ya da POST) ile yapıyoruz.

Provider uygulamasını böylece tamamlamış olduk. Client uygulamasına HTTP metodlarını içeren bir enum ekleyerek devam edelim. Bu enum yapacağımız API isteklerini yönetmemizi kolaylaştıracak. Provider içine eklediğimiz User modelinin bir benzerini Client uygulamasına da eklememiz gerekiyor. Fakat bu kez JPA annotation'larına ihtiyacımız olmayacak çünkü kullanıcıları Client uygulamasında veritabanına kaydetmeyeceğiz.

Sırada Client uygulamasının kalbi ClientJob ve Client sınıfları var.

Provider uygulamasını http://localhost:9001 adresinde çalıştırıyoruz. ClientJob sınıfı Provider uygulamasına HTTP isteğini yaptıktan sonra sonucu Either içerisinde döndürüyor. Böylece dönen cevap ya bir Throwable ya da bir User oluyor. Client uygulamasındaki fonksiyonlar geriye Promise döndürüyorlar. Dönen Promise herhangi bir controller içerisinde await fonksiyonuna verilebilir. Örnek olarak Client uygulamasında Application.index içerisinde bu fonksiyonları kullanalım. Önce bir kullanıcı oluşturalım, sonra bu kullanıcının ayrıntılarını isteyelim.

Çıktıda şu logu göreceğiz.
INFO  ~ Kullanıcı oluşturuldu: name:Foo surname:Bar

Örneği oldukça basit tutmaya çalıştım. Ancak 4Primes bünyesinde geliştirmekte olduğumuz KURAM(*) platformu da çok benzer bir yapı kullanmakta. Bu yapının oldukça karmaşık ve büyük ölçekli ortamlarda sorunsuz çalıştığını da belirtmek isterim. Umarım faydalı olmuştur.

(*): KURAM platformu bir tür Tümleşik Yönetim Bilgi Sistemi Platformu'dur. SSO, Kullanıcı ve Yetki yönetimi, Doküman Yönetimi, Log Yönetimi, Dağıtık Arama, Dağıtık Önbellek gibi özellikler sunmaktadır. KURAM hakkında yakın zamanda güzel yazılar yazabilmeyi umuyorum.

Follow me on Twitter