DataSnap Rest Server Mimari Seçimi Hakkında

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen NewMember »

Arkadaşlar Merhaba;
Delphi de bir Rest Api geliştirmeye çalışıyorum.
Ancak epey araştırmama rağmen kafamda oturmayan bazı hususlar var.

Sorularım ve kafama oturmayan hususlar RestClient ile alakalı değil.
İşin SERVER tarafıyla alakalı.

İnternette çok fazla türkçe kaynak hatta ingilizce bile çok yüzeysel.
İspanyolca ve Portekizce kaynaklar ise epey bir fazla.
Sanırım artık Delphi sadece İspanyollar kullanıyor. :wink:

Bu defa kervan yolda düzülsün istemiyorum.
Proje olgunlaştığında refactoring yapmak istemiyorum.
İllaki olacaktır ama mimari yapı değişikliği gerektiren refactoringler ile uğraşmak istemiyorum.
Daha yolun başındayım ve o yüzden de doğru yönde ilerlemek istiyorum.

Öncelikle .Net ortamında C# ile Rest Api yapabilirdim.Bu konuda yeterince bilgim var.Ancak bir kaç sebep ile bundan vazgeçtim.

1.C# ta bu işi yapınca mecburen Entity Framework kullanacağız.Çünkü alışmışız. :D
Direkt Db CRUD ları yapmayacağız.Ama Delphi tarafında ise hazır classlarım kütüphanelerim var.
Entity Framework kadar bana kolaylık sağlıyorlar ve direkt SQL ile çalıştıklarından daha performanslılar.Ayrıca ilk göz ağrımız Delphi ile daha rahat olacağımı düşünüyorum.

2.Delphi' de Serveri ISAPI.dll ile oluşturabilmenin yanında birde Exe olarak oluşturabiliyoruz ki (Kurulum,Ayar,Dağıtım v.s. için süper kolaylık) tadından yenmeyecek bir özellik.
Ama C# ile yaptığımızda (en azından ben bilmiyorum) böyle bir şansımız yok.

Bu sebeplerden dolayı Delphi ile bu işi yapmaya karar verdim.

Öğrenmek istediğim hususlar şunlar.

Model 1)Sihirbaz ile oluşturduğumuz bir Datasnap Rest Server Uygulamasında TServerMethods1 diye bir class oluşturuyor.2 adet te demo function oluşturuyor.Reversestring ve EchoString şeklinde.
Biz bu servere client üzerinden datasnap bileşenleri ile istek atacağımız zaman bu fonksiyonlara bir parametre gönderiyoruz.
Örneğin TServerMethods1 classı üzerinde GetCari diye bir methodumuz olsun.Biz bu methoda şu şekilde bir örnek URI ile istekte bulunuyoruz.

Kod: Tümünü seç

http://localhost:8080/datasnap/rest/GetCari/stringparametremiz
Bu string parametremiz bir json string olacak muhtemelen.(Tabi şart değil)

Server tarafında da biz bu fonksiyonda bu parametreyi yakalayıp, bir JsonObject nesnesine deserialize edip,
(Bu JsonObject nesnesinde Token olabilir, cari listesinin hangi kayıtları içereceğini sorgulamamız için gerekli olan Where bildirimleri olabilir, veya clientten istek atarken göndermesini isteyeceğimiz
herhangi bir bilgi olabilir.........
Sonuç olarak serverin istediği tüm bilgileri içeren bir JsonObject serialize edip string olarak servere gönderilir.Ve serverde bu stringi deserialize eder ve bu bilgilere göre yapacağı işleri yapar ve
geriye bir string sonuç döner.Örneğin bir JsonArray objesini string olarak döner.
Clientte bu JsonArray içeren stringi deserialize eder ve kullanıyıcıya gösterir veya ne yapacaksa yapar.
Update,Insert ve Delete islemlerinde de server boolean sonuç döner clientte boolean sonuca göre bu işlemlerin başarılı olup olmadığını anlar.(Tabi burda farklı dönüşlerde yapılabilir.Sadece örnek bir yaklaşım olsun diye yazıyorum.)

Burda bu modelde, bu yaklaşımda kafama takılan hususlar ve çıkardığım sonuçlar şunlar.Bunlar doğru mudur?Yoksa yanlışmı düşünüyorum.


a)Clientten gelen isteğin klasik Rest isteklerinde olduğu gibi gelen istek GET mi? PUT mu? DELETE mi? POST mu?
Bunu bilemiyoruz.Bilme şansımız yok.

Sadece GET harici atılan istekler de atılan istek durumuna göre metod isminde update, delete gibi prefixler arıyor.
Örneğin Cari isminde bir listelenen metodumuz var.
Buna

Kod: Tümünü seç

http://localhost:8080/datasnap/rest/Cari/stringparametremiz
şeklinde bir GET istek atabiliyoruz.
Ama bu URI ye POST istek attığımızda TServerMethods1 classı içinde updateCari şeklinde bir metod arıyor .
Ama bu URI ye DELETE istek attığımızda TServerMethods1 classı içinde cancelCari şeklinde bir metod arıyor .
Ama bu URI ye PUT istek attığımızda TServerMethods1 classı içinde acceptCari şeklinde bir metod arıyor .

Yani epey bir karışık geldi.

Burda şöyle bir yaklaşım olabilir belki.Tabi standartlara ne kadar uyar bilmem.

Hep tek bir uriye POST istek atılır.Gönderilen isteğin içerdiği parametre içerisinde CRUD işlemlerinden hangisinin yapılacağını belirten bir enum,const v.b. bir belirteç gönderilir.O bilgiye göre CRUD işlemlerinden hangisini yapacağını server bilir.
Tek fonksiyonla bu iş bitirilir.

b)Bütün bir projenin kodlarını tek bir Class üzerine yazmamız gerekiyor.TServerMethods1 classı.(Tabii adını değiştirebiliriz ancak bundan Cari için ayrı, Depo için ayrı, Fatura İçin ayrı yapamıyoruz)
En azından ben bu şekilde anladım.

c)En önemlisi ise bu fonksiyonlara parametre gönderirken gönderdiğimiz parametreler encode etsek bile url üzerinden gitmesi gerekiyor.
Oysaki bir clientlerden istek atarken bir Request nesnesi kullanıyoruz.
Bu requestşn bri Header bölümü, bir Body si oluyor. Tabi bazı parametrelerei QueryString olarak ta gönderiyoruz ama Header ve Body seçeneklerimiz var.

---Burda öğrenmek istediğim şey, diyelim ki bu modelleme ile Apimizi geliştirmeye başladık.İleride URI üzerinden gidecek veride bir boyut sınırlamasına takılma riskimiz varmıdır?
---Bu modelde Request nesnesi gönderme şansımız varmıdır?Benim anladığım kadarı ile yoktur.

Bütün bunlardan çıkardığım sonuç şudur.Doğru mu düşünüyorum sizce?

Bu model, Rest Apiye eğer sadece delphi ile geliştireceğimiz bir RestClient projesinden ulaşım sağlamak istiyorsak tercih edeceğimiz bir model olmalı.
Yani bu Api ye bir web uygulamasından, HTTP üzerinden bildiğimiz klasik GET,PUT,DELETE istekleri atmak istiyorsak tecih edeceğimiz bir model olmamalı.
Ama yine de buna mecbur kalırsak eğer bir web uygulamasından yada Delphi dışında bir dil ile geliştirreceğimz bir mobil uygulamadan atacağımız isteklere aşağıdaki gibi olacaktır.

GET için:

Kod: Tümünü seç

 http://localhost:8080/datasnap/rest/updateCari/stringparametremiz
POST için:

Kod: Tümünü seç

 http://localhost:8080/datasnap/rest/updateCari/stringparametremiz
DELETE için:

Kod: Tümünü seç

 http://localhost:8080/datasnap/rest/cancelCari/stringparametremiz
PUT için:

Kod: Tümünü seç

http://localhost:8080/datasnap/rest/acceptCari/stringparametremiz

Ama bu durumda da servere göndermek istedğimiz tüm veri "stringparametremiz" şeklinde url üzerinden gönderebiliriz.
Her ne kadar isteklerimizin methodlarını istek atarken POST -PUT-DELETE-GET gibi belirtsek bile pek bir esprisi olmaz sonuda yine isteğin tipi ne olursa olsun URI de metodun ismini belirtmemiz gerekir
ve sanki normal bir VCL uygulamada yaptığımız gibi salında bir metod çağırmış oluruz.Request kullanamayız.HTTP mimarisini kullanmamış oluruz.
Bir fonksiyon çağırmış oluruz ve Response ile de bu fonksiyondan dönen değeri yakalayıp işleriz.


Yani sonuç olarak eğer RestClient projemizi delphide geliştirmeyeceksek, veya delphide geliştireceksek bile Datasnap kütüphanesini implemente etmeyen bir client uygulama geliştirmeyecek isek
RestServeri bu modalde geliştirmenin hiç bir avantajı olmadığı gibi bir çok sakıncasıda var.Sizce doğru mudur?
Yada bir başka deyişle aslında Datasnap Rest Server HTTP üzerinden veri alışverişi gerçekleştirmek için HTTP mimarisini kendisi implemente etmiş ve geliştiriciyi HTTP nin detaylarından kurtararak işi SADECE bir metoda istek atıp,
dönen sonucu da işlemek olarak ifade edilebilecek bir sadeliğe indirmiş bir kütüphanedir.Sizce doğrumudur?

Model 2)
Bu modelde ise bir TWebModule nesnesi üzerinde actionlar tanımlayabiliyoruz.Ve bu actionların Request ve Response nesnelerini parametre olarak alıyor.Ve clientlerden gelen Request nesnesini burda yakalıyoruz ve
Header'inde,Body'sinde veye URL parametrestinde ki değerleri yakalayıp, gerekli işlemi yapıp, bir Response nesnesi dönebiliyoruz.

Sanırım bu modeli kullanırsak eğer TServerMethods1 classına ihtiyacımız olmuyor.
Bütün herşeyi bu WebModule nesnesi üzerinde actionlar tanımlıyoruz.
Ve bu actionların gerçekleşme anında da gelen Request nesnesinden isteğin türünün GET-POST-PUT-DELETE olduüunu çözümleyip,
GET ise GetCari methodunu,
DELETE ise DeleteCari methodunu,
PUT ise UpdateCari methodunu,
POST ise InsertCari methodunu çağırıp gerekli operasyonları yaptıktan sonra da
Response nesnesi ile cliente istedğimiz veriyi gönderiyoruz.(GET metodunda bir array gibi,Psot metodunda bir boolean değer gibi, vs....)



Örnek:

Kod: Tümünü seç

procedure TWebModule1.WebModule1CariAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);



Son olarak:

--Bu iki model birbirinin alternatifidir anladığım kadarıyla.Bu doğrumudur?
--Geliştireceğim Rest Api ye her dilde ve her platformda yazılacak her hangi bir uygulamadan erişilebilmesini isterim.
Bu durumda benim 2.Modeli kullanmam gerekir gibi geliyor bana.

Sizce bu doğrumudur?
Yada yukarıda yazdıklaım da mantık hatası veya yanlış değerlendirilen hususlar varmıdır?
Biraz uzun oldu kusura bakmayın ama, daha önceki projelerimde yaşadığım refactoring zorluklarını en aza indirebilmek için belki biraz fazla kastırmış olabilirim.
Bu konuda bilgi ve tecrübesi olan arkadaşlar bu husularda bilgilendirebilirler ise çok sevinirim.
Herkese iyi çalışmalar dilerim.
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen ertank »

Merhaba,

Mümkün mertebe datasnap kullanmayın.
1- MARS-Curiosity ( https://github.com/andrea-magni/MARS )
2- mORMot ( https://github.com/synopse/mORMot )
3- mORMot2 ( https://github.com/synopse/mORMot2 )

Bunlardan muhtemelen ilk seçenek daha kolay kullanabileceğiniz bir seçenek olacaktır. Linux, Windows olarak farklı platformları desteklemektedir. Standalone, Windows Servis uygulaması, ISAPI desteği yanlış bilmiyor isem mevcut.

mORMot yine Linux ve Windows destekler ancak ISAPI desteği olduğunu sanmıyorum. Windows ortamında windows servis uygulaması da MARS kara kolay olmayabilir. Diğer taraftan performans olarak çok hızlı çalışır.

Ben şahsen ihtiyacım olduğunda MARS kütüphanesini tercih ediyorum. Şu ana kadar bir sorunum olmadı. MARS sizin record türündeki fonksiyonlarınızı otomatik olarak JSON string haline çevirebilir. Bu anlamda kod yazma kolaylığı da vardır. Farklı versiyonlar geliştirmek istediğinizde v1 kısmı durur ve çalışır iken v2 kısmını farklı bir URL erişşimi ile aynı projeye ekleyebilirsiniz. Birden fazla veritabanı ile "connection pool" kullanarak işlem yapmaya olanak sağlar. Temel olarak FireDAC veritabanı erişim bileşenlerini destekler ancak UniDAC desteği de vardır. mORMot ile kıyaslayınca öğrenmesi daha kolaydır.
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen NewMember »

ertank yazdı: 30 Ağu 2021 05:04 Merhaba,


Bunlardan muhtemelen ilk seçenek daha kolay kullanabileceğiniz bir seçenek olacaktır. Linux, Windows olarak farklı platformları desteklemektedir. Standalone, Windows Servis uygulaması, ISAPI desteği yanlış bilmiyor isem mevcut.


Ben şahsen ihtiyacım olduğunda MARS kütüphanesini tercih ediyorum. Şu ana kadar bir sorunum olmadı. MARS sizin record türündeki fonksiyonlarınızı otomatik olarak JSON string haline çevirebilir. Bu anlamda kod yazma kolaylığı da vardır. Farklı versiyonlar geliştirmek istediğinizde v1 kısmı durur ve çalışır iken v2 kısmını farklı bir URL erişşimi ile aynı projeye ekleyebilirsiniz. Birden fazla veritabanı ile "connection pool" kullanarak işlem yapmaya olanak sağlar. Temel olarak FireDAC veritabanı erişim bileşenlerini destekler ancak UniDAC desteği de vardır. mORMot ile kıyaslayınca öğrenmesi daha kolaydır.
Çok teşekkürler.
Yeterince aydınlatıcı oldu benim için.Ancak delphi tarafında bu kadar çeşitlilik arasında bocalamayıp, kafamda bazı şeylerin tam olarak oturması için yine de şu olayı aydınlatmam lazım.
Aşağıdaki çıkarım doğrumudurç
=NewMember yazdı:Yani sonuç olarak eğer RestClient projemizi delphide geliştirmeyeceksek, veya delphide geliştireceksek bile Datasnap kütüphanesini implemente etmeyen bir client uygulama geliştirmeyecek isek
RestServeri bu modalde geliştirmenin hiç bir avantajı olmadığı gibi bir çok sakıncasıda var.Sizce doğru mudur?
Yada bir başka deyişle aslında Datasnap Rest Server HTTP üzerinden veri alışverişi gerçekleştirmek için HTTP mimarisini kendisi implemente etmiş ve geliştiriciyi HTTP nin detaylarından kurtararak işi SADECE bir metoda istek atıp,
dönen sonucu da işlemek olarak ifade edilebilecek bir sadeliğe indirmiş bir kütüphanedir.Sizce doğrumudur?
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen ertank »

Çıkarımınızı anladığımdan emin değilim. Anladığım kadarıyla;
- Alınacak bilgileri HTTP iletişiminde BODY kısmından almalısınız. GET sadece raporlama için kullanılabilir ve URL üzerinden sınırlı parametre tanımlanması faydalı olur.
- REST Client konudan bağımsızdır.
- REST Server ne ile geliştirildiği (DataSnap, MARS, mORMot, Horse, Node.JS, PHP, C#.Net) önemsizdir. Siz neyi daha iyi biliyorsanız onu kullanabilirsiniz.

Geliştirmeyi Delphi ile yapacaksanız DataSnap kullanmanızı şahsen önermem. Bunun Class, URL veya başka bir konu ile ilgisi yok. Performans olarak istemci sayısı arttıkça çok yavaşlamakta ve hatta belli sayılardan sonra çökmeler yaşanmaktadır. Ayrıca RAM kullanımı da yüksektir. Yerini tespit edememekle birlikte belli koşullarda hafıza kaçağı yaptığından da şüphelenmekteyim.
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen NewMember »

Çok teşekkür ederim.
Peki aşağıdaki model hakkında ne düşünürsünüz?
Bunda da aynı sorunlar yaşanır mı sizce?

Resim
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen ertank »

Hiç kullanmadığım için yorum yapamayacağım.
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen NewMember »

ertank yazdı: 30 Ağu 2021 11:25 Hiç kullanmadığım için yorum yapamayacağım.
Teşekkürler.
MARS-Curiosity daha detaylı incelemeye başlıyorum.
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen NewMember »

@ertank
MARS-Curiosity inceledim.Bizim manuel olarak yapmak isteyipte implemente etmek isteyeceğimiz bir çok class ve özellik eklenmiş.
Güzel bir kütüphane.
Ama bu sorumun belki bu kütüphane ile de alakası yok.Dediğim gibi biraz bu konuda bilgi eksikliğim var.Kafa karışıklığımda muhtemelen ondan geliyor.
Demolarında bir başlangıç template projesi var.SayHelloWorld diye bir metodu var.Bu metoda istek atılınca bir string ifade dönüyor.
Metodun tipi ve içeriğide çok güzel bir şekilde attribute olarak tanımlanmış.
Buraya kadar herşey güzel.Ancak ben bu metodda Request Header ve Request Body yi nasıl yakalayacağım.

Resim
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen ertank »

Authorization ve MultipartFormData örnek projelerini inceleyin.
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen NewMember »

ertank yazdı: 31 Ağu 2021 01:43 Authorization ve MultipartFormData örnek projelerini inceleyin.
Çok teşekkürler Ertan Bey.
Bu arada Andrea Magni' nin videolarını da buldum Youtube'da.
Sanırım eğlenceli ve sağlam bir geliştirme olacak.
Örnek bir videoyuda buraya bırakalım.

https://www.youtube.com/watch?v=AlwlLoeHl2w
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: DataSnap Rest Server Mimari Seçimi Hakkında

Mesaj gönderen NewMember »

ertank yazdı: 31 Ağu 2021 01:43 Authorization ve MultipartFormData örnek projelerini inceleyin.
@ertank kütüphaneyi tamamen inceledim.
Projeme implemente ettim.
Delphi üzerindeki standart mimariden giderken hazırladığım classların, modellerin, json helperlerin v.b. hepsinin daha güzel ve daha profesyonel bir şekilde kütüphaneye zaten implemete edilmiş olduğunu gördüm.
Yani kütüphanenin ne ile neyi ve nasıl yaptığına yüzde seksen olarak vakıf oldum.
Neredeyse Amerika'yı yeniden keşfetmeye çalışacakmışım.
Ayrıca kütüphane refactoringe de çok müsait.
Yönlendirmeniz için çok çok teşekkür ederim.
İyi çalışmalar.
Cevapla