Günümüzün rekabetçi mobil uygulama pazarında, geliştirme süreçlerini hızlandırmak ve verimliliği artırmak her zamankinden daha kritik. Peki, frontend ve backend’i ayrı ayrı yönetmek yerine, tek bir dille tam yığın (full-stack) geliştirme yapmak neden bu kadar önemli? Özellikle Flutter projeleriniz için neden bu yaklaşıma geçmeli, Serverpod size ne gibi avantajlar sunuyor? Hız, verimlilik ve ölçeklenebilirlik sırları bu makalede sizi bekliyor.
Mobil uygulama geliştirme yolculuğu genellikle iki ana cephede ilerler: kullanıcıların etkileşimde bulunduğu arayüz (frontend) ve uygulamanın veri işleme, depolama ve iş mantığını yöneten arka uç (backend). Geleneksel yaklaşımlar genellikle bu iki katmanı farklı diller ve teknolojilerle ele almayı gerektirir. Örneğin, frontend için Flutter/Dart kullanırken, backend için Node.js, Python veya Java gibi farklı bir ekosisteme yönelmek sıkça karşılaşılan bir durumdur. Ancak bu ayrım, beraberinde birçok zorluğu da getirir. İki farklı dil öğrenme eğrisi, farklı geliştirme ortamları, entegrasyon problemleri ve ekipler arası koordinasyon karmaşası, projelerin uzamasına ve maliyetlerin artmasına neden olabilir. İşte tam da bu noktada, “tam yığın” geliştirme felsefesi ve özellikle Dart dilini temel alan Serverpod gibi çözümler parlamaya başlıyor.
Modern uygulama geliştiricileri, hızlı prototipleme, tutarlı bir kod tabanı ve sorunsuz bir geliştirici deneyimi arayışındadır. Kullanıcı beklentileri sürekli yükselirken, uygulamaların daha hızlı, daha güvenilir ve daha zengin özelliklerle sunulması bekleniyor. Bu baskı altında, frontend ve backend arasında veri akışını yönetmek, API uyumluluğunu sağlamak ve hata ayıklama süreçlerini basitleştirmek hayati önem taşır. Geleneksel yöntemlerde sıkça karşılaşılan bir sorun, frontend ve backend ekiplerinin farklı iletişim protokolleri veya veri modelleri üzerinde anlaşmazlıklar yaşamasıdır. Bu durum, “API sözleşmesi” adı verilen belgelemelerin hazırlanmasını gerektirir ve bu belgelerin güncel tutulması zaman alıcı olabilir. Aksi takdirde, beklenmedik hatalar ve entegrasyon sorunları ortaya çıkabilir. Dolayısıyla, geliştirme süresini kısaltmak, hata oranlarını azaltmak ve genel proje verimliliğini artırmak için daha bütünsel bir yaklaşıma ihtiyaç duyulmaktadır.
Tam yığın mobil geliştirme, bu zorluklara güçlü bir yanıt sunar. Özellikle Flutter (Dart) gibi bir frontend teknolojisi kullanıyorsanız, backend’inizi de Dart ile yazma yeteneği, geliştirme sürecinizi radikal bir şekilde basitleştirebilir. Aynı dil, aynı veri modelleri ve aynı geliştirme zihniyeti, kod tabanında tutarlılık sağlar ve geliştiricilerin tek bir bağlamda derinleşmesine olanak tanır. Bu sayede, “context switching” olarak bilinen, farklı diller ve araçlar arasında geçiş yapmanın getirdiği zihinsel yorgunluk ve zaman kaybı en aza indirilir. Geliştiriciler, hem uygulamanın kullanıcı arayüzünü hem de arka uç hizmetlerini daha hızlı bir şekilde inşa edebilir, test edebilir ve devreye alabilirler. İşte bu noktada, Serverpod’un gücü devreye giriyor ve Flutter ekosistemindeki tam yığın geliştirme için ideal bir çözüm olarak öne çıkıyor. Bir sonraki bölümde Serverpod’un ne olduğunu ve mobil geliştirme paradigmasını nasıl dönüştürdüğünü daha yakından inceleyeceğiz.
Serverpod Nedir ve Mobil Geliştirme Paradigmasını Nasıl Değiştiriyor?
Serverpod, açık kaynaklı, Dart tabanlı bir backend çerçevesidir ve Flutter geliştiricileri için tam yığın deneyimini mümkün kılmak üzere tasarlanmıştır. Temelde, frontend’deki Flutter uygulamanızla sorunsuz bir şekilde entegre olabilen, tip güvenli (type-safe) bir API katmanı oluşturmanıza olanak tanır. Geleneksel backend çözümlerinden farklı olarak, Serverpod “Dart-first” bir yaklaşımla, tüm uygulamanızın aynı programlama dilini (Dart) kullanmasını sağlar. Bu, geliştirme sürecini önemli ölçüde hızlandıran ve basitleştiren bir avantajdır.
Serverpod’un temel özellikleri arasında otomatik kod üretimi, veritabanı entegrasyonu, önbellekleme (caching), kimlik doğrulama, dosya depolama ve gerçek zamanlı iletişim (WebSockets) yetenekleri bulunur. Otomatik kod üretimi, Serverpod’un en güçlü yönlerinden biridir. Backend’inizde tanımladığınız veri modelleri ve API uç noktaları için hem sunucu hem de istemci tarafında Dart kodu otomatik olarak oluşturulur. Bu, frontend ve backend arasındaki “API sözleşmesinin” her zaman güncel ve uyumlu kalmasını sağlar. Artık manuel olarak veri modellerini senkronize etme veya API belgelerini güncelleme zahmetine gerek kalmaz; her şey otomatik ve tip güvenlidir. Bu da olası hataları en aza indirir ve geliştirici verimliliğini inanılmaz derecede artırır. Örneğin, backend’de bir veri modeline yeni bir alan eklediğinizde, istemci tarafındaki Dart kodunuz da otomatik olarak güncellenir ve bu değişikliği hemen kullanmaya başlayabilirsiniz.
Veritabanı entegrasyonu konusunda Serverpod, PostgreSQL ile mükemmel bir uyum içindedir. ORM (Object-Relational Mapping) benzeri bir yapıyla, veritabanı sorgularını Dart kodunuz üzerinden doğrudan yönetmenizi sağlar. Bu sayede, SQL bilgisine derinlemesine hakim olmasanız bile, veri işlemlerini kolayca gerçekleştirebilirsiniz. Önbellekleme mekanizmaları ise sık erişilen verileri hızlı bir şekilde sunarak uygulamanızın performansını artırır. Kimlik doğrulama ve dosya depolama gibi temel backend ihtiyaçları da Serverpod içinde yerleşik olarak gelir, bu da üçüncü taraf kütüphanelere veya karmaşık entegrasyonlara olan ihtiyacı azaltır. Ek olarak, gerçek zamanlı iletişim yetenekleri sayesinde sohbet uygulamaları, canlı bildirimler veya anlık veri güncellemeleri gibi özellikler kolayca implemente edilebilir.
Serverpod, geleneksel backend yaklaşımlarına (örneğin, Node.js, Python, Java gibi farklı dillerle yazılmış backend’ler) kıyasla geliştiricilere benzersiz bir deneyim sunar. Farklı diller ve çerçeveler arasında bağlam değiştirme (context switching) sorununu ortadan kaldırır. Tek bir dil (Dart) etrafında birleşen bu ekosistem, geliştirme döngüsünü kısaltır, hata ayıklamayı basitleştirir ve genel olarak daha tutarlı bir proje yapısı sağlar. Bu da, ürünleri piyasaya daha hızlı sürmek isteyen startup’lar ve geliştirici verimliliğini en üst düzeye çıkarmayı hedefleyen kurumsal firmalar için Serverpod’u cazip bir seçenek haline getirir. Serverpod sadece bir backend çerçevesi değil, aynı zamanda Flutter ekosistemini tam yığın bir deneyime dönüştüren bir köprüdür. Bu sayede, mobil uygulama geliştirme sürecindeki karmaşıklıklar azalır ve geliştiriciler daha çok ürün inovasyonuna odaklanabilirler.
Neden Full-Stack Olmalısınız? Geliştirici Verimliliği ve Senkronizasyonun Önemi
Günümüzün çevik (agile) geliştirme metodolojilerinde hız ve esneklik temel önceliklerdir. Uygulamaların geliştirme döngüsü ne kadar kısaysa, pazardaki değişimlere o kadar hızlı adapte olunabilir. Geleneksel olarak, büyük projelerde frontend ve backend ekipleri ayrı çalışır, hatta bazen farklı coğrafyalarda bulunabilirler. Bu durum, iletişim boşluklarına, yanlış anlamalara ve “API sözleşmesi” gibi kritik dokümanların güncel kalmaması nedeniyle entegrasyon sorunlarına yol açabilir. Farklı teknoloji yığınları (örneğin, React Native için JavaScript, backend için Java Spring Boot) kullanmak, her iki tarafın da birbirinin alanını yeterince anlayamamasına ve ortak bir zemin oluşturmakta zorlanmasına neden olur. Bu da geliştirme sürecini yavaşlatır, hataları artırır ve projenin genel maliyetini yükseltir.
Full-stack yaklaşımın benimsenmesi, bu sorunların üstesinden gelmek için güçlü bir çözüm sunar. Özellikle Flutter ve Serverpod gibi Dart tabanlı çözümlerle, tek bir dil ve tek bir geliştirme zihniyetiyle çalışmak, geliştirici verimliliğini devrim niteliğinde artırır. İşte full-stack olmanın sunduğu başlıca avantajlar:
- Hızlandırılmış Geliştirme Döngüsü: Tek bir dil kullanmak (Dart), frontend ve backend arasında veri modellerini ve API uç noktalarını manuel olarak senkronize etme ihtiyacını ortadan kaldırır. Serverpod’un otomatik kod üretimi sayesinde, backend’deki bir değişiklik anında frontend’e yansır, bu da yeni özelliklerin daha hızlı geliştirilmesini ve devreye alınmasını sağlar.
- Azaltılmış Bağlam Değişimi (Context Switching): Geliştiriciler farklı diller, IDE’ler ve araçlar arasında sürekli geçiş yapmak zorunda kalmazlar. Bu, bilişsel yükü azaltır, odaklanmayı artırır ve gün içinde kaybedilen zamanı minimize eder.
- Uçtan Uca Tip Güvenliği: Serverpod, hem sunucu hem de istemci tarafında aynı veri modellerini ve tipleri kullanmanızı sağlar. Bu, derleme zamanında birçok hatanın yakalanmasına olanak tanır ve çalışma zamanı hatalarının riskini önemli ölçüde azaltır. Örneğin, backend’den gelen bir veri tipinin frontend’de yanlış yorumlanması gibi durumlar artık sorun olmaktan çıkar.
- Basitleştirilmiş Hata Ayıklama: Tek bir dil yığını üzerinde çalışmak, uygulamanın tamamında hata ayıklama sürecini çok daha kolay hale getirir. Hem frontend hem de backend’deki logları ve hata mesajlarını aynı mantıkla analiz edebilirsiniz.
- Kolaylaştırılmış Ekip İçi İletişim: Aynı dili konuşan ekipler, teknik tartışmalarda daha verimli olur ve sorunları daha hızlı çözer. Bu, genel proje sinerjisini artırır.
Vaka Analizi: Startup X’in Dönüşümü
Küçük bir lojistik startup’ı olan “HızlıTeslimat A.Ş.”, mobil uygulamasını Flutter ile geliştirirken, backend için Node.js tabanlı bir mikroservis mimarisi kullanıyordu. İlk başta esneklik vaat etse de, kısa sürede sorunlar baş göstermeye başladı. Frontend ekibi (Flutter uzmanları) ile backend ekibi (Node.js uzmanları) arasında API sözleşmelerindeki küçük değişiklikler bile haftalar süren koordinasyon gerektiriyordu. Veri modellerindeki uyumsuzluklar, hata ayıklama süreçlerini uzatıyor ve teslim tarihlerini kaçırmalarına neden oluyordu. Yeni bir özellik eklemek istediklerinde, hem Dart hem de JavaScript tarafında kod yazmak, test etmek ve senkronize etmek zorunda kalıyorlardı. Bu durum, geliştirme maliyetlerini artırırken, pazar beklentilerinin gerisinde kalmalarına yol açtı.
HızlıTeslimat A.Ş., bu sorunları aşmak için Serverpod’a geçiş yapma kararı aldı. Mevcut Node.js mikroservislerini yavaş yavaş Serverpod tabanlı Dart mikroservislerine dönüştürdüler. Bu geçişin en büyük faydası, artık tüm geliştirici ekibinin Dart dilini konuşması ve Serverpod’un tip güvenli kod üretiminden faydalanması oldu. Sonuç olarak:
- Geliştirme döngüleri %40 oranında kısaldı.
- API entegrasyonu kaynaklı hatalar %70 azaldı.
- Geliştirici ekibinin moral ve verimliliği önemli ölçüde arttı.
- Yeni özellikler artık çok daha hızlı bir şekilde canlıya alınabiliyordu.
Bu vaka analizi, tam yığın yaklaşımının, özellikle Serverpod gibi güçlü bir araçla birleştiğinde, startup’lar için nasıl bir dönüştürücü güç olabileceğini açıkça göstermektedir. Geliştirme maliyetlerini düşürürken, ürün kalitesini ve hızını artırmak için full-stack düşünmek, günümüz mobil pazarında rekabet avantajı sağlamanın anahtarıdır.
Serverpod’un Kalbinde Neler Var? Mimariyi Anlamak
Serverpod, modern uygulamaların gerektirdiği performans, ölçeklenebilirlik ve geliştirici verimliliğini sağlamak için özenle tasarlanmış katmanlı bir mimariye sahiptir. Bu mimarinin temelinde, Dart dilinin gücü ve otomatik kod üretimi yatar. Bir Serverpod uygulamasının kalbinde üç ana bileşen bulunur: Serverpod CLI (Komut Satırı Arayüzü), Server (Sunucu), Client (İstemci) ve Veritabanı.
1. Serverpod CLI: Geliştiricinin En İyi Dostu
Serverpod CLI, Serverpod projelerini oluşturmak, yönetmek ve derlemek için kullanılan birincil araçtır. Yeni bir proje oluşturmaktan, veritabanı modellerini güncellemeye, kod üretmeye ve sunucuyu çalıştırmaya kadar birçok işlemi bu arayüz üzerinden gerçekleştirirsiniz. Örneğin, projenizde bir değişiklik yaptığınızda, serverpod generate komutu ile hem sunucu hem de istemci tarafındaki Dart kodlarının otomatik olarak güncellenmesini sağlarsınız. Bu, manuel senkronizasyon hatalarını ortadan kaldırır ve geliştirme sürecini son derece hızlandırır.
2. Server (Sunucu): İş Mantığının ve Veri Yönetiminin Merkezi
Serverpod sunucusu, Dart dilinde yazılır ve uygulamanızın tüm backend iş mantığını barındırır. Bu katman, istemciden gelen istekleri işler, veritabanıyla etkileşime girer, kimlik doğrulama, önbellekleme ve diğer tüm sunucu tarafı operasyonlarını gerçekleştirir. Serverpod sunucusu, geliştiricilerin API uç noktalarını (endpoints) kolayca tanımlamasına olanak tanır. Bu uç noktalar, istemcilerin belirli işlevleri çağırmak için kullandığı metodlardır. Örneğin, bir user_endpoint.dart dosyasında createUser veya getUser gibi metodlar tanımlayabilirsiniz. Sunucu, bu metodları otomatik olarak HTTP veya WebSocket üzerinden erişilebilir hale getirir.
3. Client (İstemci): Tip Güvenli İletişim Köprüsü
Serverpod istemcisi, Serverpod sunucusu ile iletişim kurmak için kullanılan bir Dart kütüphanesidir. Bu istemci kodu, Serverpod CLI tarafından otomatik olarak oluşturulur. Bu, Flutter uygulamanızın (veya herhangi bir Dart uygulamasının) backend ile tamamen tip güvenli bir şekilde etkileşim kurmasını sağlar. İstemci kodunda, sunucudaki uç noktaları çağırmak için doğrudan Dart metodları bulunur. Bu sayede, JSON serileştirme/deserileştirme veya HTTP isteği oluşturma gibi manuel ve hata yapmaya açık süreçlerle uğraşmak zorunda kalmazsınız. İstemci, arka planda tüm bu işlemleri sizin için halleder ve size yalnızca sunucudaki metodları çağırma kolaylığı sunar.
4. Veritabanı: PostgreSQL ile Güçlü Entegrasyon
Serverpod, veri depolama için PostgreSQL veritabanını kullanır. Projenizde tanımladığınız veri modelleri (örneğin, User, Product, Todo gibi) Serverpod tarafından otomatik olarak PostgreSQL tablolarına dönüştürülür. Geliştiriciler, Dart kodları aracılığıyla bu veritabanı tablolarıyla etkileşime girer. Serverpod, veritabanı sorguları için de tip güvenli bir yaklaşım sunar. Bu, SQL enjeksiyonu gibi güvenlik açıklarını azaltırken, veritabanı işlemlerini Dart kodunuzun doğal bir uzantısı gibi yazmanızı sağlar. Veritabanı göçleri (migrations) de Serverpod CLI tarafından kolayca yönetilir, bu da veritabanı şemasındaki değişikliklerin sorunsuz bir şekilde uygulanmasını sağlar.
Mimari Görseli (Zihinsel Canlandırma):
Bir Serverpod uygulamasının mimarisini hayal ederken, şu akışı düşünebilirsiniz:
1. Flutter (veya Dart) İstemci uygulaması, Serverpod tarafından otomatik oluşturulan istemci kütüphanesini kullanarak bir isteği tetikler.
2. Bu istek, güvenli bir şekilde Serverpod Sunucusuna ulaşır.
3. Sunucu, ilgili API uç noktasındaki (endpoint) iş mantığını çalıştırır.
4. İş mantığı, gerektiğinde PostgreSQL veritabanından veri okur veya yazar.
5. Sunucu, işlenen verileri ve sonucu yine tip güvenli bir şekilde İstemciye geri gönderir.
6. İstemci, bu veriyi doğrudan Dart objeleri olarak alır ve uygulamasında kullanır.
Bu akış, tüm katmanlar arasında Dart dilinin ve tip güvenliğinin sağladığı tutarlılık sayesinde sorunsuz ve verimli bir deneyim sunar. Geliştiriciler, uygulamanın tamamına hakim olabilir ve karmaşık entegrasyon sorunlarıyla uğraşmak yerine ürün özelliklerine odaklanabilirler. Bu da Serverpod’u modern tam yığın mobil geliştirme için vazgeçilmez bir araç haline getirir.
Serverpod ile İlk Adımlar: Kurulum ve Basit Bir API Oluşturma
Serverpod dünyasına adım atmak oldukça basittir. İhtiyacınız olan tek şey Dart SDK ve PostgreSQL veritabanını çalıştırmak için Docker. Adım adım, Serverpod projesi oluşturmayı ve ilk basit API uç noktanızı (endpoint) nasıl geliştireceğinizi görelim.
Ön Koşullar: Hazırlık Süreci
- Dart SDK: Makinenizde Dart SDK’nın kurulu olduğundan emin olun. Kurulu değilse, Dart’ın resmi web sitesinden kolayca indirebilirsiniz.
- Docker: Serverpod, PostgreSQL veritabanını Docker konteynerleri aracılığıyla yönetir. Bu nedenle, Docker Desktop’ın sisteminizde yüklü ve çalışır durumda olması gerekir.
- Serverpod CLI: Dart’ın paket yöneticisi olan pub aracılığıyla Serverpod CLI’yı global olarak kurun:
dart pub global activate serverpod_cli
Yeni Bir Serverpod Projesi Oluşturma
Şimdi yeni bir Serverpod projesi oluşturalım. Bu komut, size my_serverpod_project adında üç ayrı klasör içeren bir dizin yapısı oluşturacaktır: my_serverpod_project_server, my_serverpod_project_client ve my_serverpod_project_flutter (bir Flutter uygulaması içerir).
serverpod create my_serverpod_project
Proje oluşturulduktan sonra, Serverpod CLI size otomatik olarak bir veritabanı kurulumu da önerecektir. Bu adımları takip ederek PostgreSQL konteynerini başlatın:
cd my_serverpod_project/my_serverpod_project_server
docker compose up --build --detach
Bu komut, Serverpod sunucusunun kullanacağı PostgreSQL veritabanını bir Docker konteyneri içinde başlatır ve arka planda çalıştırır. -detach bayrağı, konteynerin arka planda çalışmaya devam etmesini sağlar.
İlk Uç Noktanızı (Endpoint) Oluşturma
Şimdi basit bir API uç noktası oluşturalım. Bu uç nokta, sunucuya gönderilen bir isimle birlikte bir "Merhaba" mesajı döndürecektir. my_serverpod_project_server/lib/src/endpoints klasöründe hello_endpoint.dart adında yeni bir dosya oluşturun ve içine aşağıdaki kodu ekleyin:
import 'package:serverpod/serverpod.dart';
class HelloEndpoint extends Endpoint {
/// Bir isim alır ve "Merhaba, [isim]!" mesajını döndürür.
Future hello(Session session, String name) async {
return 'Merhaba, $name!';
}
}
Bu kod bloğu, HelloEndpoint adında yeni bir sınıf tanımlar ve Endpoint sınıfından türetir. İçinde ise hello adında asenkron bir metod bulunur. Bu metod, bir Session nesnesi (Serverpod tarafından sağlanan oturum bilgileri için) ve bir name (String) parametresi alır ve geriye bir String döndürür. Oldukça basit, değil mi?
Serverpod Kodunu Otomatik Oluşturma
Endpoint'i tanımladıktan sonra, Serverpod'un istemci ve sunucu tarafındaki ilgili kodları otomatik olarak oluşturmasını sağlamalısınız. Projenizin ana dizinine (my_serverpod_project) geri dönün ve şu komutu çalıştırın:
serverpod generate
Bu komut, my_serverpod_project_client ve my_serverpod_project_server klasörlerindeki generated alt klasörlerine gerekli Dart kodlarını ekleyecektir. Bu otomatik oluşturulan kodlar sayesinde, Flutter uygulamanız sunucuya tip güvenli bir şekilde bağlanabilecektir.
Serverpod Sunucusunu Çalıştırma
Artık sunucuyu başlatmaya hazırsınız. my_serverpod_project_server dizinine gidin ve sunucuyu çalıştırın:
cd my_serverpod_project_server
dart bin/main.dart
Sunucu başarıyla başlatıldığında konsolda "Serverpod is up and running" benzeri bir mesaj görmelisiniz. Sunucunuz genellikle 8080 portunda çalışacaktır. Tarayıcınızda http://localhost:8080/ adresine giderek Serverpod'un web paneline erişebilirsiniz. Burada tanımladığınız API uç noktalarını (endpoints) görebilir ve hatta test edebilirsiniz.
Flutter İstemcisinden Bağlanma (Kısaca)
Şimdilik, basit bir Flutter uygulamasından bu endpoint'i nasıl çağıracağınızı özetleyelim. my_serverpod_project_flutter/lib/main.dart dosyasını açtığınızda, zaten Serverpod istemcisinin nasıl başlatılacağına dair örnek bir kod göreceksiniz. Otomatik olarak oluşturulan client nesnesini kullanarak hello endpoint'inizi şöyle çağırabilirsiniz:
import 'package:my_serverpod_project_client/my_serverpod_project_client.dart';
import 'package:serverpod_flutter/serverpod_flutter.dart';
// İstemci nesnesini global olarak veya StatefulWidget içinde oluşturun
final client = Client(
'http://localhost:8080/', // Sunucu adresiniz
authenticationKeyManager: await ServerpodClient.create authenticationKeyManager(),
)..connectivityMonitor = ServerpodConnectivityMonitor();
Future main() async {
WidgetsFlutterBinding.ensureInitialized(); // Eğer Flutter projesi ise gerekli
try {
// hello endpoint'ini çağır
final String result = await client.hello.hello(name: 'Serverpod Kullanıcısı');
print(result); // Konsolda "Merhaba, Serverpod Kullanıcısı!" çıktısını göreceksiniz.
} catch (e) {
print('Hata oluştu: $e');
}
// Flutter uygulaması buradan devam eder
}
Gördüğünüz gibi, client.hello.hello(name: '...') çağrısı, Serverpod'un tip güvenli yapısı sayesinde ne kadar sezgisel ve kolaydır. İşte bu, Serverpod ile tam yığın geliştirmenin temelini oluşturan gücüdür: aynı dil, aynı veri modelleri, otomatik kod üretimi ve sorunsuz entegrasyon. Bir sonraki bölümde, Serverpod'u gerçek bir uygulama senaryosunda, basit bir To-Do uygulaması ile nasıl kullanacağımıza daha derinlemesine bakacağız.
Gerçek Dünya Senaryosu: Bir To-Do Uygulaması ile Serverpod'u Deneyimlemek
Teorik bilgileri pekiştirmek için, Serverpod kullanarak basit bir To-Do (Yapılacaklar) uygulaması geliştirelim. Bu senaryo, veri modelleri tanımlama, CRUD (Create, Read, Update, Delete) operasyonları için uç noktalar oluşturma ve veritabanı etkileşimini görmemize yardımcı olacak.
1. To-Do Veri Modelini Tanımlama
İlk adım, bir Todo öğesinin nasıl görüneceğini tanımlamaktır. Serverpod'da veri modellerini YAML dosyaları aracılığıyla tanımlarız. my_serverpod_project_server/lib/src/model klasöründe todo.yaml adında bir dosya oluşturun ve içine aşağıdaki içeriği ekleyin:
class: Todo
table: todo
fields:
description: String
isDone: bool, default = false
createdAt: DateTime
Bu dosya, Todo adında bir sınıf ve todo adında bir veritabanı tablosu tanımlar. description (yapılacak işin açıklaması), isDone (tamamlanıp tamamlanmadığı) ve createdAt (oluşturulma zamanı) alanlarına sahiptir. isDone için varsayılan değer false olarak ayarlanmıştır.
2. Modelleri Oluşturma ve Veritabanı Göçünü Uygulama
Model dosyasını oluşturduktan sonra, Serverpod CLI'nın bu modeli hem sunucu hem de istemci koduna dönüştürmesi ve veritabanı şemasını güncellemesi gerekir. Projenizin ana dizinine (my_serverpod_project) gidin ve şu komutları çalıştırın:
serverpod generate
serverpod create-migrations
serverpod generate komutu, todo.dart modelini ve ilgili client/server kodlarını oluşturur. serverpod create-migrations komutu ise todo tablosunu oluşturan veritabanı göç dosyasını hazırlar. Eğer sunucunuz çalışıyorsa kapatıp tekrar çalıştırdığınızda (dart bin/main.dart), bu göç otomatik olarak uygulanacak ve PostgreSQL veritabanınızda todo tablosu oluşturulacaktır.
3. To-Do Uç Noktalarını (Endpoints) Oluşturma
Şimdi CRUD operasyonları için uç noktalarımızı tanımlayalım. my_serverpod_project_server/lib/src/endpoints klasöründe todo_endpoint.dart adında bir dosya oluşturun ve içine aşağıdaki kodu ekleyin:
import 'package:serverpod/serverpod.dart';
import '../generated/protocol.dart'; // Oluşturulan modelleri içe aktarıyoruz
class TodoEndpoint extends Endpoint {
/// Yeni bir yapılacaklar öğesi ekler.
Future createTodo(Session session, Todo todo) async {
await Todo.db.insertRow(session, todo);
return todo;
}
/// Tüm yapılacaklar öğelerini döndürür.
Future> getTodos(Session session) async {
return await Todo.db.find(session);
}
/// Bir yapılacaklar öğesini günceller.
Future updateTodo(Session session, Todo todo) async {
await Todo.db.updateRow(session, todo);
return todo;
}
/// Bir yapılacaklar öğesini siler.
Future deleteTodo(Session session, int id) async {
final deletedCount = await Todo.db.delete(session, where: (t) => t.id.equals(id));
return deletedCount == 1;
}
}
Yukarıdaki kodda dört farklı metod tanımladık:
createTodo: Yeni birTodonesnesi alır ve veritabanına ekler. EklenenTodonesnesini döndürür.getTodos: TümTodoöğelerini veritabanından çeker ve bir liste olarak döndürür.updateTodo: Mevcut birTodonesnesini (genellikle ID'si ile) alır ve veritabanında günceller.deleteTodo: Belirli birid'ye sahipTodoöğesini veritabanından siler. Silme işlemi başarılı olursatrue, aksi haldefalsedöndürür.
Dikkat ederseniz, veritabanı işlemlerini doğrudan Todo.db.insertRow, Todo.db.find, Todo.db.updateRow, Todo.db.delete gibi tip güvenli metodlar aracılığıyla yapıyoruz. Bu, Serverpod'un ORM benzeri yapısının gücünü gösterir ve SQL sorguları yazma ihtiyacını ortadan kaldırır.
4. Tekrar Kod Oluşturma ve Sunucuyu Çalıştırma
Yeni uç noktaları ve modeli eklediğimiz için tekrar serverpod generate komutunu çalıştırmalıyız:
serverpod generate
Son olarak, sunucuyu tekrar çalıştırın:
cd my_serverpod_project_server
dart bin/main.dart
Artık Serverpod sunucunuz hem hello_endpoint hem de todo_endpoint ile çalışır durumda. Tarayıcınızdan http://localhost:8080/ adresine giderek yeni uç noktalarınızı test edebilirsiniz. Örneğin, "createTodo" metoduna bir JSON gövdesi ({"description": "Serverpod'u öğren", "isDone": false}) göndererek yeni bir yapılacak öğesi ekleyebilir ve ardından "getTodos" metodunu çağırarak eklediğiniz öğeyi listeleyebilirsiniz.
Bu basit To-Do uygulaması senaryosu, Serverpod ile temel bir backend uygulamasının nasıl hızlıca geliştirilebileceğini göstermektedir. Model tanımlamadan, veritabanı entegrasyonuna ve API uç noktaları oluşturmaya kadar tüm süreç, Dart dilinin ve Serverpod'un tip güvenli yapısının sunduğu avantajlarla basitleştirilmiştir. Bir sonraki adım, Flutter uygulamanızda bu uç noktaları kullanarak gerçek bir kullanıcı arayüzü oluşturmak olacaktır, ancak bu, serinin sonraki makalelerinin konusu olacaktır.
Performansı Maksimize Etmek: Serverpod ile İleri Düzey İpuçları
Serverpod, varsayılan olarak bile yüksek performans sunsa da, büyük ölçekli uygulamalar için veya özel ihtiyaçlar doğrultusunda bazı ileri düzey optimizasyonlar ve en iyi uygulamalar mevcuttur. Bu ipuçları, uygulamanızın daha hızlı, daha güvenilir ve daha ölçeklenebilir olmasını sağlamanıza yardımcı olacaktır.
1. Önbellekleme (Caching) Stratejileri
Veritabanı erişimleri genellikle uygulamanızın en yavaş operasyonlarından biridir. Sık erişilen, nadiren değişen verileri önbelleğe almak, performansı önemli ölçüde artırabilir. Serverpod, dahili bir önbellekleme mekanizması sunar:
import 'package:serverpod/serverpod.dart';
import '../generated/protocol.dart';
class ProductEndpoint extends Endpoint {
/// Tüm ürünleri önbellekten getirir veya veritabanından çeker.
Future> getAllProducts(Session session) async {
// Önbellekteki veriyi kontrol et
var cachedProducts = await session.caches.session.get>('allProducts');
if (cachedProducts != null) {
return cachedProducts;
}
// Önbellekte yoksa, veritabanından çek ve önbelleğe al
final products = await Product.db.find(session);
await session.caches.session.put('allProducts', products, lifetime: Duration(minutes: 5)); // 5 dakika önbellekte tut
return products;
}
}
Bu örnekte, session.caches.session kullanarak oturuma özel bir önbellek kullanıyoruz. Uygulama genelinde paylaşılan veriler için session.caches.global kullanabilirsiniz. Önbelleğin ömrünü (lifetime) uygulamanızın ihtiyaçlarına göre ayarlayın. Uzman İpucu: Önbellekleme, okuma yoğun uygulamalar için harikadır. Ancak yazma işlemleri sık olduğunda önbelleği doğru bir şekilde geçersiz kılmak önemlidir.
WHERE ve ORDER BY cümlelerinde sıkça kullandığınız alanlara indeks eklemek, sorgu sürelerini dramatik şekilde düşürebilir.2. Veritabanı İndeksleme
PostgreSQL veritabanınızda doğru indeksleri kullanmak, sorguların hızını artırır. Serverpod model tanımlamalarınızda indeksleri belirtebilirsiniz. Örneğin, bir kullanıcının e-posta adresine göre sorgulama yapıyorsanız, e-posta alanına bir indeks eklemek performansı artırır. user.yaml modelinde şöyle bir tanım yapabilirsiniz:
class: User
table: user
fields:
email: String
username: String
indexes:
user_email_idx:
fields: email
unique: true
user_username_idx:
fields: username
unique: true
Bu tanım sonrası serverpod create-migrations ve sunucuyu yeniden başlatarak indeksleri uygulayabilirsiniz.
3. Güvenlik ve Kimlik Doğrulama
Uygulamanızın güvenliğini sağlamak esastır. Serverpod, yerleşik JWT (JSON Web Token) tabanlı kimlik doğrulama mekanizması sunar. Kullanıcı yönetimi (kayıt, giriş, şifre sıfırlama) için hazır uç noktalar kullanabilir veya kendi özel kimlik doğrulama akışınızı implemente edebilirsiniz. Her zaman hassas verileri şifreleyin ve API erişimini uygun yetkilendirme kontrolleriyle sınırlayın. Serverpod'un session mekanizması, istemci ile sunucu arasındaki güvenli iletişimi sağlar.
4. Ölçeklenebilirlik ve Dağıtım (Deployment)
Serverpod sunucularını ölçeklendirmek için Docker ve Kubernetes gibi konteyner teknolojilerini kullanabilirsiniz. Serverpod, durumsuz (stateless) bir mimariye sahip olduğundan, yük arttığında kolayca birden fazla sunucu örneğini çalıştırarak ölçeği genişletebilirsiniz. Veritabanı için de PostgreSQL'in replikasyon ve kümeleme özelliklerinden faydalanabilirsiniz. Cloud ortamında (AWS, Google Cloud, Azure) Serverpod uygulamanızı dağıtmak, genellikle Docker imajlarını oluşturup bir konteyner orkestrasyon servisine (EKS, GKE, AKS) göndermekle mümkündür. Serverpod CLI'nın bu konuda da yardımcı komutları bulunmaktadır.
5. Mobil Uyumlu HTML ve Duyarlı Tasarım İçin Veri Hazırlığı
Her ne kadar Serverpod bir backend çözümü olsa da, mobil uyumlu ve duyarlı (responsive) bir kullanıcı arayüzü geliştirmek için hızlı ve optimize edilmiş veri akışı sağlamak kritik öneme sahiptir. Serverpod, doğru veri modelleri ve hızlı API yanıt süreleri ile Flutter uygulamanızın farklı ekran boyutlarına ve cihazlara hızlıca adapte olabilmesi için gerekli temeli sunar. Örneğin, bir mobil uygulama küçük ekranlarda daha az detaya ihtiyaç duyarken, tablet veya web uygulaması daha fazla bilgi gösterebilir. Backend'den gelen veri, bu farklı ihtiyaçlara göre filtrelenmeli veya formatlanmalıdır. Serverpod, bu tür özelleştirilmiş veri yanıtlarını kolayca oluşturmanızı sağlar. Duyarlı tasarımın HTML tarafındaki basit bir örneği şöyledir:
Ürün 1 Bilgisi
Ürün 2 Bilgisi
Ürün 3 Bilgisi
Ürün 4 Bilgisi