Dart web server oluşturmak [Rehber]

Dart programlama dili ile web server oluşturmayı konu alacağım uzun soluklu yazıma hoşgeldiniz. Okumaya başlamadan önce çayınızı, kahvenizi hazırlayın. Dart programlama dilinin temelinden itibaren yola çıkacağımız bu yazıda bazı kütüphaneleri de beraberinde kullanarak bir web server nasıl oluşturulur, nasıl deploy edilir elim döndüğünce anlatacağım. 🙂

Dart diline bir bakış

Dart programlama dilinin asıl kullanım amacı nedir?

Dart, kendi websitesinde de belirttiği üzere bir client optimized programlama dilidir. Peki bu ne anlama gelir? Client tarafında optimize edilmiş programlama dilleri UI oluşturma ve bu arayüzlerin kullanıcı ile olan etkileşimlerini geliştirme (UX) alanında gelişmiş teknikler sunar. Dart, Google’dan aldığı destekle beraber kısa zamanda çok hızlı yol kat eden bir programlama dili olması nedeniyle her platformda varlığını göstereceğini iddia etmektedir. Tam Flutter için biçilmiş kaftandır. 🙂

Client optimize olması nedeniyle Dart programlama dilinin ilerleyen yıllarda veritabanı, request handling gibi konularda bir Java veya C# gibi gelişmiş ve native destekleri olmayacak. Elbette bu demek değildir ki geliştiriciler bu konuda bir şey yapamaz. Pub sayesinde Dart dilinin CLI uygulamalarında kullanılacak farklı ve çeşitli işler yapan kütüphaneleri siz de geliştirebilirsiniz. Bu nedenden dolayı ilerleyen yıllarda Dart dilinin tıpkı Node.JS gibi bir runtime environment’a sahip olacağını düşünüyorum.

Dart VM

Dart programlama dili, Dart VM sayesinde AOT (Ahead of Time) ve JIT (Just In Time) derleme seçenekleri sunar ve bu derleme biçimlerini Dart VM üzerinde native kodlara çevirdiği için tıpkı bir Java VM gibi çalışır demek yanlış olmaz. Dart’ın aynı anda AOT ve JIT derlenmesi durumu karmaşık olduğu için Dart VM’in geliştiriciler için büyük bir iş yaptığını belirtmek de doğru olur. Dart VM ile beraber yazdığınız tüm kodları her platformda native hale çevirebilir ve uygulamalarınıza ARM, Intel gibi farklı mimarilere dahi uygun yazabilirsiniz.

Dart programlama dilinin esnekliği

Bazı programlama dilleri sizi kısıtlarken bazıları da istediğiniz her şeyi yapmanıza olanak sağlar. Örneğin Rust programlama dilinde race condition oluşturmanız imkansızken, C programlama dilinde bunu basit bir mantık hatasıyla çabucak oluşturabilirsiniz. Javascript ile az kod yazmanın projenizi basitleştirdiğini düşünürken uygulama çalıştırıldığında tahmin edilemeyecek noktalarda hataların oluşması normaldir. Birden kendinizi nesneye yönelimli programlama dili ve fonksiyonel programlamaya uygun dillerin karşılaştırmasını yaparken bulursanız, hatırlayın ki Dart programlama diliyle beraber hem nesne tabanlı programlama, hem de %100 bir şekilde fonksiyonel programlama prensiplerini uygulayarak kod yazabilirsiniz. Bu esneklikler ve çeşitlilikler Dart programlama dilini hem Desktop, hem Web, hem CLI hem de mobil uygulamalar için en uygun programlama dili yapıyor.

Dart dilinin esnekliğini okuduk, kullanım alanlarını öğrendik, her türlü programlama prensibine uygun yazılabileceğini de öğrendik. Peki Dart ile herkes Flutter uygulamaları yaparken başka neler yapabiliriz?

Dart ile web server oluşturmak!

Dart her platforma uyum sağlayan bir programlama dili. Tıpkı içine konduğu her kabın şeklini alan kediler gibi. 🙂 Hem çevik, hem esnek ayrıca her ortama uyum sağlıyor. Flutter ile mobil uygulamalar ve web uygulamaları yazarken, çıkaracağımız ürünün ön yüzünü yazarken, yine aynı kullandığımız programlama diliyle beraber arka yüzünü de yazabiliriz. İşte tam da bu yazının konusu bu. 🙂

Web server yazmaya girişmeden önce Aqueduct gibi çözümlerden de bahsetmek istiyorum. Aqueduct sürekli güncellenmese de biraz uğraştırıcı bir çözüm. Multi thread desteği sunan, Dart diliyle bir sunucu oluşturmanızı sağlıyor. Bizim yapacağımız proje ise daha basit olacak ve farklı kütüphaneler kullanacak. 🙂

Temel kütüphaneler ile server oluşturmak

Ek paketler indirmeden önce temel kütüphaneler ile bir HTTP istekleri işleyen sunucu oluşturalım. Terminal üzerinden bir Dart projesi açalım.

dart create server_project

Daha sonrasında oluşturulan proje dosyalarını kod editöründe veya IDE üzerinde açalım.

Klasörleri ve dosyalara Flutter projesinden aşinasınızdır muhtemelen. bin klasörü içerisinde, main.dart dosyasında ana fonksiyonumuz bulunmakta. Main içerisinde bir sunucu oluşturalım.

  final address = InternetAddress.loopbackIPv4;
  const port = 8080;
  final httpServer = await HttpServer.bind(address, port);
  print('Sunucu baslatildi: ${address} port: ${port}');

Daha sonrasında terminalden komutla sunucumuzu localhost üzerinde ayağa kaldıralım.

dart run bin/server_project.dart

Terminal ekranında print ile yazdığımız localhost ve port bilgilerini görüntüleyebilirsiniz. Dilerseniz tarayıcıdan sayfayı açabilirsiniz fakat şu an için boş dönecektir. 🙂

HTTP istekleri işleyen bir sunucunun en önemli özelliği istekleri düzenli işleyebilmektir. Bunun için bir metot oluşturalım.

  await for (HttpRequest request in httpServer) {
    request.response.write('İlk Dart sunucusundan selam!');
    await request.response.close();
  }

httpServer üzerinden gelen tüm istekleri işleyen bir for döngüsü yazmış bulunmaktayız. Şu an için GET,POST veya path fark etmeksizin tüm isteklere aynı dönütü gönderiyor. Eğer istersek döngü içerisine bir switch case yazarak gelen istekleri POST, GET gibi istek tiplerine ayırabiliriz.

    switch (request.method) {
      case 'GET':
        request.response.write('GET isteği');
        break;
      case 'POST':
        request.response.write('POST isteği');
        break;
      default:
        request.response.write('Method Not Allowed');
        request.response.statusCode = HttpStatus.methodNotAllowed;
    }
  }
Dart http web server
Tüm kod

Peki farklı tip URL uzantılarında farklı veriler göndermek istiyorsak ne yapmalıyız?

Shelf Router ile Dart Web Server

Shelf router, Google’da çalışan bir geliştirici tarafından yazılmış, web isteklerini yönetmeye yarayan bir Dart kütüphanesi. Eğer yalnızca backend tarafında çalıştırılacaksa kullanılmalıdır. Flutter uygulamalarında bu tarz kütüphanelerin yeri yok. 🙂

Pubspec dosyanıza shelf router paketini ekledikten sonra main dosyamızı modifiye etmeye başlayalım.

  var app = Router();

Shelf router ile modifiye edeceğimiz sunucumuzu önce Router objesi oluşturalım. Bu Router objesi ile birlikte tüm uzantıları denetleyebileceğiz.

  app.get('/', (Request req) async{
    return Response.ok('Main Page');
  });

app.get ile beraber index uzantısına gelen tüm isteklere ‘Main Page’ yazısını göndermiş olacağız.

  app.get('/', (Request req) async{
    if (req.method == 'GET') {
      return Response.ok('Main Page GET');
    }
    if (req.method == 'POST') {
      return Response.ok('Main Page POST');
    } else {
      return Response.ok('Method Not Allowed');
    }
  });    

Eğer istersek gelen tüm istekleri method türlerine ayırarak denetleyip, her method için farklı bir response çevirebiliriz.


  app.get('/create/user/<user>', (Request request, String user) {
    return Response.ok('response ok $user');
  });

Bir kullanıcı oluşturmak için gönderilen web isteğinde <user> yerine yazılan ismi rahatlıkla elde edebiliriz. Eğer farklı verilerle uğraşmanız gerekiyorsa, request.headers ile birlikte gönderilen tüm header verisine ulaşabilir ve bunu parse edebilirsiniz.

  var server = await io.serve(app, 'localhost', 8080);

Tüm uzantıları yazdım, her isteği karşılıksız bırakmadım, her lafa bir cevabım var diyorsanız da yukarıdaki kod parçacığı ile sunucunuzu localhost üzerinde çalıştırabilirsiniz. 🙂



Son olarak en önemlisi Dart dili ile yazdığınız web server nasıl deploy edilir? Ne tür hizmetleri kullanmak gerekir?

Deploy Dart Server

Google Cloud Platform, Heroku gibi servislerle kurduğunuz Dart sunucusunu deploy edebilirsiniz. Bu kısmı şu an için eksik bırakıyorum. Eğer Dart ile web server kurma konusuna ilgi yoğun olursa, deploy işlemleri için detaylı bir yazı oluşturmayı planlıyorum. Muhtemelen de bu yazının bu kısmından da o yazıya bir link vereceğim. 🙂

Dart programlama dilini kullanarak web server kurmayı öğrendik. Eğer isterseniz firedart gibi kütüphanelerden yararlanarak Firebase’deki veritabanınız için bir ara katman oluşturabilirsiniz. Eğer istemezseniz mongo_dart gibi kütüphaneleri kullanarak da CRUD işlemleri yapabileceğiniz bir sunucu oluşturabilirsiniz. Dart ile yapabileceğiniz şeylerin sınırı sizin kendi çizdiğiniz sınırlardır. Bu sınırları aşmak ve genişletmek için yapabileceğiniz tek şey de kod yazmaktır. 🙂


Okuyucuya Not

Merhaba okuyucu! Blogum son zamanlarda yüksek trafik almaya başladı ve bu durumdan memnunum fakat aynı zamanda siz ziyaretçileri tatmin edememekten endişeliyim. 🙂 Eğer yazılarım ile ilgili bir tavsiyeniz olursa mail adresimden bana ulaşabilir veya Twitter üzerinden direct message gönderebilirsiniz. Github’ta örnek olarak yaptığım projelere göz atmak isterseniz de bu linki kullanabilirsiniz. Umarım bu ziyaretinizle size bir şeyler katabilmişimdir.

Sağlıcakla kalın!