28 May

WSDL Soap Web Servis Karmaşası

Bu konu üzerine bir iki yazım oldu. Ama gelen aramalardan ve sorulardan görebildiğim kadarı ile çok fazla karmaşa hakim. Olayı basite indirgemek için tüm terimleri özetlemeye çalışacağım.
Web Servis : Farklı veya aynı platformlar arasında; örneğin php ile yazılmış web uygulamanızın asp.net uygulaması ile iletişim kurabilmesi web servis ile mümkündür.
İki farklı dil, iki farklı platform. Peki iletişim nasıl mümkün olacak. Her ikisinin de aynı dili konuşmasını nasıl sağlayacağız.
Burada devreye SOAP girmektedir. Açılımı “Simple Object Access Protocol” dur. SOAP’ı bir kurallar bütünü olarak tanımlayabiliriz. PHP ile ASP.NET’in konuşabilmesi için SOAP’ın koyduğu kurallara uygun hareket etmeleri gerekiyor. Bu kuralları burada açmayacağım, amacım sadece kavram karmaşasını bir nebze azaltmak.

SOAP’ı kurallar bütünü olarak tanımladık, bu kuralların yazılı olması gerekiyor ki kalıcı olsun 🙂 İşte bu yazılı kurallara da WSDL diyebiliriz. WSDL iki platform arasında iletişimi SOAP protokolü ile sağlar. SOAP protokolüne uygun olarak, gönderilecek komutların tanımlanmasını da WSDL sağlar.

WSDL alan istemci (client) , hanki interface’e sahip olduğunu. Bu interface’de hangi fonksiyon ve metodları bulunduğunu bilir ve buna göre karşı tarafa istek yapabilir.

1
$istemci= new SoapClient("http://sunucu.com/kurallar.wsdl");

Yukarıdaki satırın yorumu şudur : Gidip sunucu.com dan wsdl dosyasını al ve yönergelere göre kullandığım dile uygun hale getir. Eğer wsdl içerisinde listele gibi bir metod tanımlanmış ise :

1
$istemci->listele();

Şeklinde kullanabilirsiniz. WSDL ile hangi metodların,fonksyionların olduğu. Hangi parametreleri alabileceği, parametrelerin tipleri. Zorunlu olup olmadıkları gibi kuralları WSDL ile belirlersiniz. Bu belirlenen kurallar sunucu ve istemi tarafında yorumlanarak iletişim sağlanır.

Webden aşina olduğumuz HTTP bir protokoldür ve bu protokole göre browser ile sunucu anlaşmasını sağlar. Browserın neyi nasıl görüntüleyeceğini de HTML ile belirleriz.
SOAP ile WSDL bağlantısı da bu şekildedir. SOAP iletişimin nasıl yapılacağını belirten protokol, WSDL de iletişim kuracak sistemlerin nasıl davranmaları gerektiğini tanımlayan kural listesidir.

Web servis, SOAP ve WSDL kavramlarını bu düzleme indirdikten sonra ayrıntılandırırsanız anlaşılması daha kolay olur diye düşünüyorum.

Peki , html çok kolay oluşturuluyor ve Html yorumlamayı browser yapıyor. Ben WSDL’i nasıl oluşturacağım ve SoapClient’a nasıl yorumlatacağım 🙁

Web servis iletişiminde WSDL birkez oluşturulur ve gerekmedikçe değiştirilmez ve sadece hizmeti verecek taraf, yani server tarafı sorumludur bu işten. Genelde WSDL’i elle oluşturmak için kurduğunuz server tarafının otomatik olarak üretilmesini sağlayacak araçlar kullanılır. WSDL’i elle sıfırdan oluşturmak karmaşıktır.
Bu yüzden istemci tarafından bakarak, istemci tarafnda bize ne gibi bir görev düştüğüne bakalım.

Size web servis ile iletişim kuracağınız ve WSDL adresi verildiğinde “eyvah, ben ne yapacağım!” demenize gerek yok. İlk yapmanız gereken, mümkünse web servisi yazan kişi-kurum ile iletişim kurarak döküman rica etmeniz. Çünkü WSDL kuralları okunabilen , kısmen okunduğu kısmı ile anlaşılabilen bir yapıya sahip olsa da, hangi fonksiyonu ne zaman nerede kullanacağınızı ancak dökümantasyondan öğrenebilirsiniz.

İstemci tarafısınız, WSDL’i ve dökümanı aldınız, okudunuz ve anladınız. Bundan sonra yapmanız gereken tek şey SoapClient nesnesine gerekli parametreleri vererek istediğiniz şeyleri yapmasını sağlamanız :

1
2
3
 $client = new SoapClient("http://test-sunucusu.com/komut-tanimlamalari.wsdl"); // wsdl dosya isimlendirmesi tamamen uydurmadır, bir zorunluluk yoktur isimlendirmede
$parametre = array("a"=>1,"b"=>2);
$client->buFonksiyonWsdlDeTanımlı($parametre);

Yukarıdaki örnekde WSDL içerisinde buFonksiyonWsdlDeTanımlı diye bir fonksiyon olduğunu, bu fonksiyonunda bir array aldığını anlıyoruz.

Umarım daha fazla kavram karmaşasına sebep olmamışımdır.
Sorularınız için konu altına yorum bırakabilirsiniz.

16 Aug

Eclipse ile WSDL Oluşturma

Web servis ile uğraşırken, en çok sıkıntı yaratan şey WSDL oluşturmak sanırım. En yalın hali ile XML den ibaret bir dosya olmasına rağmen , çok fazla ayrıntı olması bu işi zorlaştırıyor.

Ama,WSDL dosyasını HTML gibi , gerekli etiketleri kullanarak, bir yazı editörü ile oluşturabilmek de mümkün. Biz kolay yöntemi kullanarak , Eclipse yardımı ile WSDL dosyasını oluşturacağız.

Eclipse ile WSDL dosyasını oluşturabilmek için, yeni bir proje açarak veya var olan proje içerisinde
File -> New -> Other adımlarını takip ettiğimizde, karşımıza çıkan pencerede bulunan Web Services başlığı altındaki, WSDL File seçip “Next”e tıklayarak bir diğer adıma geçin.

Bu adımda WSDL dosyamıza bir ad vererek bir diğer adıma geçin.

Bu adımda bulunan “Target namespace” yazan alana, benzersiz bir url yazın (örnek için var olan kayıdı değiştirmeseniz de olur)

“Prefix” alanına da herhangi birşey yazabilirsiniz , örneğin “tns” yerine “orn” yazabilirsiniz.
Buradaki “Create WSDL skeleton” seçeneğinde bulunan işareti kaldırın, çünkü bize örnek bir WSDL oluşturmasını istemiyoruz, kendimiz sıfırdan oluşturacağız.

Bu işlemden sonra “Finish”e tıkladığımızda, bir kaç satır koddan oluşan bir sayfa gelir karşımıza. Bu sayfa “Source” ve “Design” olmak üzere iki bölüm vardır. Biz “Design” bölümünü kullanacağız, burası görsel olarak WSDL’i oluşturabileceğimiz bölümdür.

WSDL oluşturmaya geçmeden önce, web servisimizin ne olacağını ve ne görev yapacağını belirlemeliyiz. Böylece WSDL’imizi de bu yapılacak işlere göre oluşturacağız.

Web servisimiz bir stok servisi olsun, urun stok durumunu kontrol edebilen ve stoğu listeleyebilen , ürünün stok durumunu gösterebilen bir servisimiz olsun. Bu web servisde kullanılacak sınıfımız da aşağıdaki gibi olsun :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class StokYanit {
   public $mesaj;
   public $kod;
   public function __construct($mesaj,$kod){
      $this->mesaj=$mesaj;
      $this->kod=$kod;
   }
}
class Urun {
   public $id;
   public $ad;
   public $renk;
   
   public function __construct($id,$ad,$renk){
      $this->id=$id;
      $this->ad=$ad;
      $this->renk=$renk;
   }
}

class Stok {
   public function liste(){}
   public function kontrolEt(Urun $urun){
      return new StokYanit($urun->ad.' ürünüden x adet kalmıştır',100);
   }
}

Yukarıdaki kod sadece sistemin işleyişini anlatabilmek için oluşturuldu. Şimdi geçelim bu stok servisimizin WSDL’ini oluşturmaya.
Az önce bahsettiğim gibi , “Design” bölümünü kullanacağız. Design bölümüne tıkladığımızda karşımıza boş bir sayfa çıkacaktır. Bu sayfada bir alana sağ tıklayalım :

– Add Service
– Add Binding
– Add PortType

ve daha birkaç seçeneğin de olduğu bir menü çıkar. Bu menüden bu üç seçeneği yazdım, çünkü en çok kullanacağımız seçenekler bunlar.

Şimdi , yukarıdaki Class’ın WSDL’imizde karşılığını oluşturacağız. Böylece web servisimizi kullanarak sistemimizde stok işlemeleri yapılabilecek.

Add PortType bir port ekler, burada servisin yapısını oluşturmamızı sağlar (Bizim örneğimizde IStok, bu adlandırmayı rastgele yaptım) .

Add Service ile bir servis oluşturulur, servis çağrısının yapılacağı konumu belirtmemizi sağlar (endpointURI burada tanımlanır)

Add Binging ile de Service ve PortType arasında bağ kurulması sağlayan “Binding” nesnesi oluşturulur.

Burda en önemli ve en karmaşık olan bölüm “Add PortType”. Çünkü bu seçenek ile servisimizin yapısını oluştururuz.

Buraya kadar anlattıklarımı video olarak aşağıda bulabilirsiniz. Tek tek resim ekleyerek anlatmak uzun ve zor olacağından böyle bir yöntem seçtim. Yalnız ses problemini aşamadığım için videoda ses yok.

Videoyu izlemeye geçmeden önce yukarıda bulunan kodlardaki “Class”lara iyi bakın, çünkü WSDL de bu yapıyı kuracağız.

Eclipse ile WSDL oluşturma from Ersin DOĞAN on Vimeo.

Konu ile ilgili daha fazla bilgi vermek gerek, yalnız ayrıntı fazla olduğu için , konuyu dağıtmadan nasıl tamamlayabileceğimi bilemediğim için, yazıyı burada kesiyorum. Aklınıza takılan şeyleri burda yorum olarak yazarsanız, konun devamını yorumlardan sürdürebiliriz.

Güzel günler dileği ile.

17 Mar

WSDL nedir ?

Aslında konu başlığı çok iddalı dursa da, bu yazımda WSDL’e dair çok ayrıntıya girmeyeceğim. Bloguma yazı yazarken, hoşgeldin mesajında belirttiğim gibi, işime yarayan veya çok yaramış, paylaştığım zaman yararlı olacağını düşündüğüm konular üzerine yazmaya çalışıyorum. Birşeyleri sıfırdan öğretmek gibi bir misyonum olmadı hiç, çoğunlukla tamamlayıcı bilgi tarzında yazıyorum.

Böyle bir açıklama gereği duydum, çünkü WSDL konusu çok ayrıntılı ve burada sadece bir fikir oluşturabilme biçiminde anlatmaya çalışacağım. Ayrıca daha öncesinde yazdığım yazıların karakteristiğine dair birşeyler yazmak istedim. Arada fırça atan oluyor, “becerememişsin” diye 🙂

WSDL (Web Service Description Language – Webservis Belirtme Dili) web servis belirtimi için model sağlayan XML tabanlı bir dildir .(*)

Önceki yazımda Web Servis konusuna giriş yampıştım. Web servis oluşturma işlemi, örneğimizde görüldüğü kadar kolay yapılabiliyor olsa da, iş bukadar ile bitmiyor. Çünkü, bizim örneğimiz sadece PHP uygulamaları arasında uyumlu olarak çalışır. Yazdığınız web servisi Java,C# veya diğer bir programlama dili ile konuşturamayız.

Bunu başarabilmek için onların da anlayacağı dilden konuşuyor olmamız gerekir. SOAP XML mesajlaşma tabanlı bir sistem entegrasyon yöntemidir evet, ama bu SOAP isteklerini oluşturmak için de bir standart gerekmektedir ( farklı platform veya dillerin birbirleri ile uyumlu çalışabilmelerini sağlayabilmek için ).
İşte burada WSDL devreye girmektedir. WSDL de XML tabanlı bir sistemdir. WSDL gerçekleştirilebilecek bütün SOAP isteklerinin kayıtarını tutar :

  • Web servisin adı (örneğimizde SMS di)
  • Yapılabilecek yordam çağrıları
  • Bu yordam çağrılarının alabileceği parametreler
  • Parametrelerin tipleri
  • Döndürülecek cevap,biçimi
  • Hata zamanında döndürülecek mesaj -sonuç (Fault)
  • Web servis çağrılarının yapılacağı adres (EndpointURI)

Bunlar sayılabilecek en temel özelliler.

Şimdi örneğimizden yola çıkarak biraz ayrıntıya girelim. Örneğimizdeki SMS servisine uygun bir WSDL oluşturduğumuzu varsayıyoruz ( WSDL oluşturma işlemine dair birşeyler yazabilmeyi umuyorum, zamanım olursa).
Bunu SoapClient nesnemize parametre olarak verdiğimizde :

$istemci=new SoapClient(“sms.wsdl”);

artık istemcimiz hangi adrese ne gibi çağrılar yapabileceğini, bu çağrıları nereye yapabileceğini, ne tür cevaplar alabileceğini bilecektir. Biz istemcimizde $istemci->buMetodYok(); çalıştırmaya çalıştığımızda ,isteği daha suncuya göndermeden bize hata döndürecektir. Çünkü WSDL de tanımlanmış böyle bir metod yok.

WSDL’imizi oluşturduktan sonra bunu farklı platformlarda kullanılabilmesi için dağıtabiliriz. Örneğin servisiniz PHP’de yazılmıştır ve WSDL oluşturarak C# ile yazılmış bir uygulamanın sizin uygulamanız ile iletişim kurmasını sağlayabilirsiniz.

PHP de veri tipleri yoktur, örneğin C# da:

int sayi;

tanımlı bir değişken tanımladığınızda buna sayı haricinde birşey atamanız mümkün değildir. Atamaya kalktığınızda hata alırsınız. Ama bu PHP’de böyle değildir :

1
2
$sayi=0;
$sayi="bu artık bir sayı değil";

Dedikki, PHP’de yazdığımız servisi C# ile kullandırabileceğiz. İyide veri tipleri aynı değil ki, nasıl anlaşacak bunlar ?
WSDL ile anlaşacaklar. WSDL’de standart veri tipleri vardır ve bunların dışına çıkılmaz, istemciler bu veri tiplerini kendi platform/programlama diline göre bir karşılığını bularak eşleştirir. Böylece platform/dil bağımsız iletişim mümkün olur.

Son olarak işin en can alıcı ve en üzücü kısmına geldi. PHP WSDL’in otomatik oluşturulması için bir araç sunmuyor şimdilik. Bunu elle oluşturmalısınız, ya da üçüncü parti bir uygulama-framework bulup bunun ile oluşturmalısınız.
Diğer birçok programlama dili WSDL’i direkt olarak koddan oluşturabilmekte, ayrıca var olan bir WSDL den istemci konudunu otomatik oluşturabilmektedir. Biz de bunu eclipse ile yapacağız ilerleyen zamanlarda.

Anlaşılmayan, hatalı yazılmış yerler olursa, yorum düşerek uyarır iseniz düzeltirim.

Hoşça kalın.

14 Feb

PHP ile web servis oluşturmak

Sanırım ilk önce web servis nedir, neden gereklidir kısaca buna değinmek gerek. İnternette çokca kaynak bulabilirsiniz bu konuda, güzel anlatılmış ,bolca teknik terimler ile desteklenmiş. Ama ben farklı bir yaklaşım tarzı ile, mümkün olduğunca sade bir biçimde ele almaya çalışacağım.

Güzel bir uygulama geliştirdik, güzel güzel çalışıyor. Ama gün geldi farklı bir platformdan,farklı fiziksel bir yerdeki bir uygulama ile iletişim kurması, veri alışverişi yapması gerekti. Ne yapacağız, o dili mi öğreneceğiz ?  İşte bu durumda web servisler devreye giriyor.

Web servis ile, internet üzerinde herhangi bir platformdaki, herhangi bir dille yazılmış bir uygulama ile veri alışverişi gerçekleştirebiliriz. Bunu sadece veri alışverişi olarak sınırlamak da pek doğru değil, ama girişte bunun böyle bilinmesi sanırım yeterli olacak.

Konumuza bir örnek ile devam edelim. Bir siteniz var ve bu sitenizden kullanıcılarınız üyelik sistemi ile yararlanabiliyor. Bu sistemde kullanıcılarınıza SMS ile bilgi vermeye yarayan bir özellik aktif etmek istiyorsunuz. Ama bu servisi kontrol etmek elimizde değil, bu yüzden farklı bir yerden satın almak zorundayız. Biz SMS servisini satın aldıktan sonra, satıcı bize SMS gönderme işlemini kendi uygulamamız içerisinde gerçekleştirebilemiz için bir API (Applcation Programing Interface Uygulama Geliştirme Arayüzü) sunar. İşte bu API lerin iletişim yöntemlerinden biri de web servislerdir.

Yukarıda da bahsettiğimiz gibi, farklı platformlarımız var, ve bunların birbiri ile anlaşması gerekiyor. İşte burda da SOAP devreye giriyor. SOAP (Simple Object Access Protocol , Basit Nesne Erişim Protokolü). Tabiki ne bu bahsettiğimiz API çağrıları için, ne de web servis işlemleri için tek protokol SOAP değildir. Ama burda vereceğim örnekteki amaç SOAP dır.

PHP ile web servis geliştirme işlemi gerçekten çok kolaydır. Bunu iki farklı yöntem ile gerçekleştirebiliriz. Birincisi WSDL yardımı ile, ikincisi WSDL olmadan direkt PHP sınıfları ile. Birinci seçenek farklı bir yazımın konusu olacağından, ikinci yönteme geçelim.

Sistemin işleyebilmesi için bir sunucu , bir de istemci olması gerekiyor. Her ikisinin farklı yerde , farklı platform/dil de olması gerekiyordu, bizim örneğimizin işlevselliğini gösterebilmek için. Ama elimizde şu anda PHP var ve bu yüzden diğer özellikleri bir kenera bırakarak salt PHP ile yolumuza devam ediyoruz.

İlk önce sunucu tarafındaki kodlarımızı oluşturalım :

1
2
3
4
5
6
7
8
9
10
11
<?php
class SMS {
   public function gonder($mesaj,$konu,$kime){
      return 'mesaj gonderildi';    
        }
}
 $sunucu=new SoapServer(null,array('uri'=>'http://ersindogan-testuri'));

$sunucu->setClass('SMS');

$sunucu->handle();

Yukarıdaki kodumuzun içeriği bir anlamda tam değil, sadece uzak yordam çağrısı yapacağız, bize bir sonuç döndürmesi yeterli. Bu yüzden SMS mesajını başarılı bir biçimde göndermiş gibi yapan bir sunucu oluşturduk. Evet birkaç satır kod ile bunu başardık. Şimdi kısaca anlatmatya çalışayım yukarıdaki kodu :

SMS diye bir sınıf oluşturduk, bu sınıfımız SMS göndermeye , SMS gönderme işleminin sonucunu döndürmeye yarıyor. Sunucu olarak oluşturduğumuz nesne bir SoapSever nesnesi. Bu SoapServer nesnemiz, gelen uzak yordam çağrılarının, belirlenen şartlar doğrultusunda çalıştırılmasını ve sonucunun istemciye döndürülmesini sağlamak ile görevli.
Burda SoapServer nesnemize, SMS sınıfını baz almasını ve bu nesnenin metodlarını çalıştırabileceğini söyledik. Eğer bunun dışında çalıştırılması istenenen sınıf-fonksiyon çağrısı gelirse SoapServer istemciye hata döndürecektir.

SoapSever nesnemizi burda WSDLsiz oluşturduk ,WSDLsiz oluşturduğumuz için bir URI (Uniform Resource Identifier Tekörnek Kaynak Tanımlayıcı) tanımlamamız gerekir, bu uri herhangi bir benzersiz url olabilir. Bunu değiştirip değiştirmemek size kalmış. Daha sonra sunucumuzun baz alacağı nesnemizi tanımlıyoruz, son olarak da handle metodu ile de sunucumuzun gelen isteklere cevap vermesini sağlıyoruz. Şimdi de istemci tarfımızı oluşturalım.

1
2
3
4
<?php
$istemci=new SoapClient(null,array('uri'=>'http://ersindogan-testuri','location'=>'http://localhost/test/sunucu.php'));
var_dump($istemci->gonder('mesaj','konu','kime'));
?>

İşte istemci tarafımızda bitti. Yukarıdaki kodu anlatmadan önce, web sunucunuzda test diye bir klasör oluşturup içerisine sunucu.php ve istemci.php adında iki dosya ekleyin. sunucu.php dosyasına sunucu ile ilgili kodları ekleyin, istemci.php dosyasına da istemci ile ilgili kodları kopyalayıp dosyaları kaydedin. Daha sonra adres satırından http://localhost/test/istemci.php yazdığımızda

string ‘mesaj gonderildi’ (length=16)

biçiminde bir mesaj verecektir.
Şimdi en son yazdığımız kodu anlatabiliriz. Yukarıdaki kodda, istemcimiz , belirtilen sunucudaki metodu çağırdı ve sonucu aldı.
Çoğunlukla bu tür işlemleri aynı makinada, aynı platformda, hatta aynı programlama dilinde bile yapmazsınız. Taraflar hep farlıdır, ama anlaşma metodu ortaktır. İşte bu ortak nokta yardımı ile uzak sistemden bir yordam çağrısı yaparak işlemlerimizi gerçekleştirebiliriz.
Konuyu elimden geldiğince toparlayarak anlatmaya çalıştım, eksik -anlaşılmayan yerler olursa yorum düşerseniz cevaplarım mutlaka.
Bu konunun bir sonraki adımı WSDL de görüşmek üzere, hoşça kalın.