Full-stack mobil geliştirme sürecinde hız ve verimlilik arayanlar için Flutter ve Serverpod ideal bir ikili. Bu makalede Serverpod kurulumu ve ilk proje adımlarını öğrenerek güçlü bir backend oluşturacaksınız.
Günümüz dijital dünyasında mobil uygulamalar hayatımızın vazgeçilmez bir parçası haline geldi. Kullanıcılar, hızlı, akıcı ve güvenilir deneyimler beklerken, geliştiriciler de bu beklentileri karşılayacak modern araçlara ihtiyaç duyuyor. Full-stack mobil geliştirme, hem kullanıcı arayüzünü (frontend) hem de sunucu tarafı mantığını (backend) kapsayan karmaşık bir süreçtir. Geleneksel yaklaşımlar genellikle farklı teknolojilerin bir araya getirilmesini gerektirir, bu da geliştirme süresini uzatabilir ve entegrasyon zorlukları yaratabilir. Peki, bu süreci nasıl daha verimli, daha hızlı ve daha keyifli hale getirebiliriz?
İşte tam bu noktada, Flutter ve Serverpod ikilisi devreye giriyor. Flutter, Google tarafından geliştirilen, tek bir kod tabanıyla iOS, Android, Web ve masaüstü platformlarında çalışan uygulamalar oluşturmanızı sağlayan popüler bir UI çerçevesidir. Serverpod ise, Flutter uygulamaları için özel olarak tasarlanmış, tip güvenli bir açık kaynaklı backend çerçevesidir. Dart dilini kullanarak hem frontend hem de backend geliştirebilme yeteneği sunarak, tam anlamıyla “full-stack Dart” deneyimi sağlar. Bu güçlü kombinasyon, geliştirme sürecini basitleştirir, hataları azaltır ve genel uygulama performansını artırır.
Bu makalede, Serverpod’un ne olduğunu, neden bu kadar önemli olduğunu ve geliştirme ortamınızı nasıl hazırlayacağınızı adım adım inceleyeceğiz. Ardından, Serverpod’u nasıl kuracağınızı, ilk projenizi nasıl oluşturacağınızı ve Flutter uygulamanızla nasıl entegre edeceğinizi pratik örneklerle göstereceğiz. Amacımız, sıfırdan başlayan bir geliştiricinin bile Serverpod ile full-stack mobil geliştirme dünyasına kolayca adım atmasını sağlamaktır. Hazırsanız, Serverpod ile modern ve performanslı bir backend kurmanın detaylarına dalalım!
Serverpod, Flutter uygulamalarıyla sorunsuz bir şekilde entegre olmak üzere özel olarak tasarlanmış, açık kaynaklı bir backend çerçevesidir. Peki, piyasada bu kadar çok backend çözümü varken neden Serverpod’u tercih etmelisiniz? Cevap oldukça basit: Dart tabanlı olması, tip güvenliği, yüksek performans ve geliştirme hızını ön planda tutan bir mimari sunmasıdır. Geleneksel full-stack geliştirme süreçlerinde, genellikle frontend için JavaScript/TypeScript tabanlı bir çerçeve (React, Vue, Angular) ve backend için farklı bir dil (Node.js, Python, Go, Java) kullanılır. Bu durum, iki farklı dil öğrenmeyi, iki farklı ekosistemi yönetmeyi ve aralarındaki iletişimi sağlamak için karmaşık API sözleşmeleri oluşturmayı gerektirir. Serverpod bu karmaşıklığı ortadan kaldırır.
Serverpod’un temel amacı, backend ve frontend arasındaki sürtünmeyi en aza indirmektir. Dart dilini kullanarak hem Flutter uygulamanızı hem de Serverpod backend’inizi yazabilirsiniz. Bu “full-stack Dart” yaklaşımı, kod tabanında tutarlılık sağlar, geliştirme sürecini hızlandırır ve hataların önüne geçmeye yardımcı olur. Örneğin, frontend’de bir veri modelini değiştirdiğinizde, Serverpod otomatik olarak backend tarafındaki ilgili kodu güncelleyebilir. Bu tip güvenli jenerasyon mekanizması, geleneksel REST API’lerde sıkça karşılaşılan veri uyumsuzluğu sorunlarını ortadan kaldırır. Böylece, geliştiriciler veritabanı şemasından API endpoint’lerine ve istemci tarafındaki veri modellerine kadar tüm katmanlarda tutarlı bir geliştirme deneyimi yaşar.
Serverpod ayrıca, yerleşik olarak WebSocket desteği, dosya yükleme, kimlik doğrulama, görüntü işleme ve hatta bir ORM (Object-Relational Mapping) ile birlikte gelir. Bu özellikler, bir uygulamanın backend ihtiyaçlarının büyük bir kısmını tek bir çerçeve içinde karşılayarak, geliştiricilerin farklı kütüphaneler ve servisler arasında geçiş yapma ihtiyacını azaltır. Performans açısından bakıldığında, Serverpod C++’a derlenen ve bu sayede oldukça hızlı çalışan DartVM üzerinde çalışır. Bu, özellikle gerçek zamanlı uygulamalar ve yüksek trafikli servisler için önemli bir avantaj sağlar. Ayrıca, Serverpod’un ölçeklenebilirlik yetenekleri, uygulamanızın büyüdükçe performansını koruyabilmesini sağlar.
Özetle, Serverpod, modern mobil uygulama geliştiricileri için tasarlanmış bir güç merkezidir. Geliştirme sürecini basitleştirir, hızlandırır ve tip güvenliği sayesinde daha az hataya yol açar. Flutter ile mükemmel bir uyum içinde çalışarak, geliştiricilerin tek bir dil ve ekosistemde tam teşekküllü, performanslı ve ölçeklenebilir full-stack uygulamalar oluşturmasına olanak tanır. Bu sayede, geliştiriciler backend entegrasyonuyla boğuşmak yerine, kullanıcı deneyimine ve iş mantığına odaklanabilirler. Gelin, bu güçlü aracı yakından inceleyelim ve kurulum sürecine başlayalım.
Geliştirme Ortamı Nasıl Hazırlanır: Serverpod Kurulumunun Ön Koşulları Nelerdir?
Serverpod ile çalışmaya başlamadan önce, sisteminizde belirli araçların kurulu olduğundan emin olmanız gerekir. Bu ön koşullar, Serverpod projenizi başarıyla oluşturmanız, çalıştırmanız ve yönetmeniz için hayati öneme sahiptir. Endişelenmeyin, bu adımlar genellikle basit ve takip etmesi kolaydır. Gelin, adım adım hangi araçlara ihtiyacımız olduğunu ve bunları nasıl kuracağımızı inceleyelim.
Dart SDK ve Flutter SDK Kurulumu
Serverpod ve Flutter, Dart dilini kullandığı için, sisteminizde Dart SDK’nın ve Flutter SDK’nın kurulu ve doğru şekilde yapılandırılmış olması şarttır. Flutter SDK, Dart SDK’yı kendi içinde barındırdığı için genellikle sadece Flutter SDK’yı kurmak yeterli olacaktır. Eğer henüz kurulu değilse, Flutter resmi web sitesindeki kurulum talimatlarını takip etmelisiniz. Kurulumdan sonra, terminalinizde aşağıdaki komutları çalıştırarak her şeyin yolunda olup olmadığını kontrol edebilirsiniz:
flutter doctor
Bu komut, eksik bağımlılıkları veya yapılandırma sorunlarını size bildirecektir. Gerekli tüm tik işaretlerini görene kadar önerilen düzeltmeleri uyguladığınızdan emin olun. flutter doctor komutunun çıktısı, iOS, Android, Web geliştirme için gerekli bileşenlerin yanı sıra Dart SDK'sının da durumunu gösterecektir.
Docker Kurulumu
Serverpod, varsayılan olarak veritabanı (PostgreSQL) ve Redis gibi arka plan servislerini Docker konteynerleri aracılığıyla yönetir. Bu, geliştirme ortamınızı hızlı ve tutarlı bir şekilde kurmanıza olanak tanır. Eğer Docker sisteminizde kurulu değilse, Docker resmi web sitesinden işletim sisteminize uygun sürümü indirip kurmanız gerekmektedir. Docker Desktop, Windows ve macOS kullanıcıları için en kolay seçenektir. Kurulumdan sonra, Docker'ın çalıştığından emin olmak için terminalinizde aşağıdaki komutu çalıştırabilirsiniz:
docker --version
Bu komut, Docker sürümünü göstermelidir. Ayrıca, Docker Desktop uygulamasının çalıştığından ve arka planda konteynerleri yönetmeye hazır olduğundan emin olun.
PostgreSQL ve Redis (İsteğe Bağlı ama Önerilir)
Serverpod'un temel kurulumu, Docker aracılığıyla bir PostgreSQL veritabanı ve Redis önbellek sunucusu kurmanızı sağlar. Bu servisleri manuel olarak kurmak zorunda kalmazsınız, ancak Serverpod'un bunları kullanabilmesi için Docker'ın doğru şekilde çalışıyor olması önemlidir. Docker konteynerleri, Serverpod projenizin ilk başlatılmasında otomatik olarak ayağa kalkacaktır. Geliştirme ortamınız için bu iki servisin ayrı ayrı manuel kurulumuna gerek yoktur, Serverpod sizin için halledecektir.
Geliştirme Ortamı (IDE) Seçimi
Flutter ve Serverpod geliştirme için Visual Studio Code (VS Code) veya IntelliJ IDEA gibi güçlü bir IDE'ye ihtiyacınız olacaktır. Her iki IDE de Dart ve Flutter için mükemmel eklentilere sahiptir. VS Code, genellikle daha hafif ve hızlı olması nedeniyle tercih edilirken, IntelliJ IDEA'nın ücretli Ultimate sürümü daha kapsamlı özellikler sunar. Seçim sizin kişisel tercihinize bağlıdır. İlgili eklentileri kurduğunuzdan emin olun (örneğin, VS Code için "Dart" ve "Flutter" eklentileri). Bu eklentiler, kod tamamlama, hata ayıklama, kod biçimlendirme ve diğer birçok üretkenlik özelliğini sağlar.
Tüm bu ön koşullar yerine getirildiğinde, Serverpod kurulumuna ve ilk projemizi oluşturmaya hazırız. Bu hazırlık adımları, sorunsuz bir geliştirme deneyimi için temel oluşturur ve Serverpod'un tüm özelliklerinden tam olarak yararlanmanızı sağlar. Şimdi, Serverpod'u sistemimize kurma ve projemizi başlatma zamanı!
Serverpod Kurulumu ve İlk Projeyi Başlatma: Adım Adım Rehber
Geliştirme ortamımızı başarıyla hazırladığımıza göre, artık Serverpod'u kurmaya ve ilk projemizi hayata geçirmeye hazırız. Bu süreç oldukça basittir ve birkaç temel komutla tamamlanabilir. Serverpod, geliştirme akışını kolaylaştırmak için güçlü bir CLI (Command Line Interface) aracı sunar. Bu CLI, proje oluşturmaktan veritabanı yönetimine kadar birçok görevi yerine getirmemizi sağlar.
Serverpod CLI Kurulumu
Serverpod'u sistemimize kurmanın ilk adımı, serverpod_cli paketini küresel olarak aktif etmektir. Bu sayede terminalinizden serverpod komutunu doğrudan çağırabilirsiniz. Terminalinizi açın ve aşağıdaki komutu çalıştırın:
dart pub global activate serverpod_cli
Bu komut, serverpod_cli paketini indirip sisteminizde kullanılabilir hale getirecektir. Kurulumun başarıyla tamamlandığından emin olmak için aşağıdaki komutu çalıştırarak Serverpod CLI sürümünü kontrol edebilirsiniz:
serverpod --version
Eğer bir sürüm numarası görüyorsanız, serverpod_cli başarıyla kurulmuş demektir. Herhangi bir hata alırsanız, genellikle PATH değişkeninizde bir sorun olabilir veya Dart SDK kurulumunuzu tekrar kontrol etmeniz gerekebilir.
Yeni Bir Serverpod Projesi Oluşturma
CLI aracımız hazır olduğuna göre, şimdi ilk Serverpod projemizi oluşturalım. Yeni bir proje oluşturmak için serverpod create komutunu kullanırız. Bu komut, Serverpod için gerekli tüm temel proje yapılarını ve dosyalarını otomatik olarak sizin için oluşturacaktır. Terminalinizde projenizi oluşturmak istediğiniz dizine gidin ve aşağıdaki komutu çalıştırın:
serverpod create my_serverpod_project
Burada my_serverpod_project, projenizin adıdır. Kendi projeniz için anlamlı bir isim seçmelisiniz. Bu komut çalıştırıldığında, Serverpod üç ana proje paketi içeren bir dizin yapısı oluşturacaktır:
my_serverpod_project_server: Backend mantığını, API endpoint'lerini, veritabanı modellerini ve diğer sunucu tarafı kodlarını barındırır.my_serverpod_project_client: Frontend uygulamanızın (Flutter) backend ile iletişim kurmasını sağlayan tip güvenli API istemcisini içerir. Bu paket otomatik olarak generate edilir.my_serverpod_project_flutter: Temel bir Flutter uygulaması şablonunu ve Serverpod client'ı ile entegrasyonu barındırır.
Proje oluşturma işlemi tamamlandıktan sonra, Serverpod size bir sonraki adımlar hakkında bilgi verecektir. Genellikle, yeni oluşturulan projenin ana dizinine geçmeniz ve gerekli bağımlılıkları indirmeniz istenir.
cd my_serverpod_project
flutter pub get
flutter pub get komutu, hem Flutter uygulamasının hem de Serverpod server ve client paketlerinin tüm bağımlılıklarını indirir. Bu, projenizin tüm parçalarının doğru bir şekilde çalışabilmesi için kritik bir adımdır. Bağımlılıklar indirildikten sonra, artık Serverpod projenizi çalıştırmaya hazırsınız.
Serverpod Projesini Çalıştırma
Serverpod projesini çalıştırmak için, my_serverpod_project_server dizinine gidip dart bin/main.dart komutunu kullanabiliriz. Ancak Serverpod, Docker konteynerleri aracılığıyla veritabanı ve diğer servisleri yönettiği için, daha kolay bir yol sunar. serverpod generate komutu, backend kodunuzda yaptığınız değişiklikleri (özellikle veritabanı modelleri ve endpoint'ler) otomatik olarak algılar ve client kodunu günceller. İlk çalıştırma için ise, genellikle sadece server dizininde başlatma komutunu kullanmak yeterlidir:
cd my_serverpod_project/my_serverpod_project_server
docker compose up --build --detach
dart bin/main.dart
İlk komut, Docker konteynerlerini (PostgreSQL ve Redis) arka planda başlatır. --build konteyner imajlarını inşa eder, --detach ise konteynerleri arka planda çalıştırmanızı sağlar. İkinci komut ise Serverpod sunucusunu başlatır. Sunucu başarıyla başlatıldığında, terminalinizde "Serverpod listening on port 8080" gibi bir çıktı görmelisiniz. Bu, backend'inizin artık istekleri dinlemeye hazır olduğu anlamına gelir.
Bu adımlarla, Serverpod CLI'yi kurmuş, ilk projenizi oluşturmuş ve sunucuyu başarıyla başlatmış olursunuz. Artık, Flutter uygulamanızın bu backend ile nasıl konuşacağını ve temel API endpoint'lerini nasıl oluşturacağımızı keşfetmeye geçebiliriz.
İlk Serverpod Projesi: Temel Bir API Nasıl Oluşturulur ve Test Edilir?
Serverpod kurulumunu tamamladık ve ilk projemizi başarıyla başlattık. Şimdi sıra, Serverpod backend'imizin gerçek bir iş yapmasını sağlamakta: temel bir API endpoint'i oluşturmak ve bunu test etmek. Serverpod'da API endpoint'leri, lib/src/endpoints klasöründe yer alan Dart sınıfları aracılığıyla tanımlanır. Bu sınıflar, client tarafından çağrılabilecek metodları içerir.
Yeni Bir Endpoint Oluşturma
Varsayılan olarak, Serverpod projeniz lib/src/endpoints/example_endpoint.dart adında bir örnek endpoint ile gelir. Bu dosyayı açarak nasıl bir yapıya sahip olduğunu inceleyelim:
// lib/src/endpoints/example_endpoint.dart
import 'package:serverpod/serverpod.dart';
class ExampleEndpoint extends Endpoint {
Future hello(Session session, String name) async {
return 'Merhaba, $name!';
}
}
Yukarıdaki kod bloğu, ExampleEndpoint adında bir sınıf tanımlar ve bu sınıf Endpoint sınıfından türetilir. hello metodu, client tarafından çağrılabilecek bir API endpoint'idir. Bu metod, bir Session nesnesi (bağlam bilgileri için) ve bir name parametresi alır ve "Merhaba, [name]!" şeklinde bir string döndürür. Bu, bir kullanıcının adını alıp ona özel bir karşılama mesajı gönderebileceğiniz basit bir örnektir.
Şimdi, bu endpoint'i kendimiz çalışır hale getirelim. Öncelikle, sunucumuzun çalıştığından emin olmalıyız. Eğer Serverpod sunucunuzu kapatmışsanız, my_serverpod_project/my_serverpod_project_server dizininde aşağıdaki komutlarla yeniden başlatın:
docker compose up --detach
dart bin/main.dart
Client Tarafından Endpoint Çağırma
Serverpod'un en güçlü özelliklerinden biri, client kodunun otomatik olarak generate edilmesidir. Backend'inizdeki bir endpoint'i her değiştirdiğinizde veya yeni bir endpoint eklediğinizde, serverpod generate komutunu çalıştırmanız gerekir. Bu komut, my_serverpod_project_client paketini güncelleyecek ve client uygulamanızın (Flutter) backend ile tip güvenli bir şekilde iletişim kurmasını sağlayacaktır.
cd my_serverpod_project
serverpod generate
Bu komut, Serverpod projenizin ana dizininde (my_serverpod_project) çalıştırılmalıdır. Başarılı bir şekilde çalıştığında, my_serverpod_project_client/lib/src/protocol.dart ve my_serverpod_project_client/lib/src/client.dart dosyaları güncellenecektir. Şimdi Flutter uygulamamızdan bu endpoint'i nasıl çağıracağımıza bakalım.
my_serverpod_project_flutter dizinine gidin ve lib/main.dart dosyasını açın. Burada, varsayılan bir Flutter uygulaması bulacaksınız. Serverpod client'ını kullanarak hello endpoint'ini çağırmak için bazı değişiklikler yapmamız gerekecek. main.dart dosyasını aşağıdaki gibi güncelleyelim:
// my_serverpod_project/my_serverpod_project_flutter/lib/main.dart
import 'package:flutter/material.dart';
import 'package:my_serverpod_project_client/my_serverpod_project_client.dart';
import 'package:serverpod_flutter/serverpod_flutter.dart';
var client = Client(
'http://localhost:8080/',
)
..connectivityMonitor = ServerpodConnectivityMonitor();
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Serverpod Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
String _helloMessage = 'Henüz mesaj yok';
final TextEditingController _nameController = TextEditingController();
void _callHelloEndpoint() async {
try {
final response = await client.example.hello(_nameController.text);
setState(() {
_helloMessage = response;
});
} catch (e) {
setState(() {
_helloMessage = 'Hata: $e';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: _nameController,
decoration: const InputDecoration(
labelText: 'Adınız',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _callHelloEndpoint,
child: const Text('Selamla!'),
),
const SizedBox(height: 20),
Text(
_helloMessage,
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
),
);
}
}
Bu kod, basit bir giriş alanı ve bir buton içeren bir Flutter uygulaması oluşturur. Butona basıldığında, _callHelloEndpoint metodu client.example.hello() çağrısını yapar ve Serverpod backend'imizdeki hello endpoint'ini tetikler. Gelen cevap ("Merhaba, [adınız]!") ekranda gösterilir. Bu örnek, Serverpod'un tip güvenli client-server iletişimini ne kadar kolaylaştırdığını açıkça göstermektedir.
serverpod generate komutunu çalıştırmayı unutmayın. Aksi takdirde, Flutter uygulamanız eski client kodunu kullanmaya devam edebilir ve hatalara yol açabilir.
Veritabanı Entegrasyonu: PostgreSQL ile Serverpod Nasıl Konuşur?
Modern uygulamaların çoğu, verileri kalıcı olarak depolamak için bir veritabanına ihtiyaç duyar. Serverpod, PostgreSQL ile mükemmel bir entegrasyon sunar ve bir ORM (Object-Relational Mapping) aracı aracılığıyla veritabanı işlemlerini basitleştirir. Bu bölümde, Serverpod ile nasıl veritabanı modelleri oluşturacağımızı, bu modelleri veritabanına nasıl migrate edeceğimizi ve veritabanı işlemlerini nasıl gerçekleştireceğimizi inceleyeceğiz.
Veritabanı Modeli Tanımlama
Serverpod'da veritabanı modelleri, .yaml dosyaları aracılığıyla tanımlanır. Bu dosyalar, lib/src/models dizini altında yer alır. Bir model tanımladığımızda, Serverpod CLI bu YAML tanımını kullanarak hem veritabanı tablolarını hem de client ve server tarafı için Dart model sınıflarını otomatik olarak generate eder. Bu, tip güvenliğini ve geliştirme hızını artıran kilit bir özelliktir.
Basit bir "Todo" listesi uygulaması için bir model oluşturalım. my_serverpod_project_server/lib/src/models/todo.yaml adında yeni bir dosya oluşturalım ve içine aşağıdaki içeriği ekleyelim:
# my_serverpod_project_server/lib/src/models/todo.yaml
class: Todo
table: todos
fields:
description: String
isCompleted: bool, default = false
Bu YAML dosyası, Todo adında bir model ve todos adında bir veritabanı tablosu tanımlar. Modelimiz iki alan içerir: description (String) ve isCompleted (bool). isCompleted alanı için varsayılan değer false olarak ayarlanmıştır.
Modeli Generate Etme ve Veritabanına Migrate Etme
YAML dosyasını oluşturduktan sonra, Serverpod'a bu modeli işlemesi için talimat vermemiz gerekir. Bunun için projenin ana dizininde serverpod generate komutunu tekrar çalıştırmalıyız:
cd my_serverpod_project
serverpod generate
Bu komut, my_serverpod_project_server/lib/src/generated dizini altında todo.dart ve diğer ilgili dosyaları oluşturacaktır. Aynı zamanda client tarafı için de my_serverpod_project_client/lib/src/protocol.dart dosyasına Todo modelini ekleyecektir. Bu otomatik jenerasyon, manuel kod yazma hatasını ortadan kaldırır.
Model sınıfları oluşturulduktan sonra, bu modeli veritabanımıza uygulamamız gerekir. Serverpod, veritabanı şemasını yönetmek için migrasyon (migration) mekanizmasını kullanır. Sunucunuzu çalıştırırken terminale geri dönün ve serverpod create-migration komutunu çalıştırın:
cd my_serverpod_project/my_serverpod_project_server
serverpod create-migration
Bu komut, migrations dizini altında yeni bir migrasyon dosyası oluşturacaktır. Bu dosya, todos tablosunu oluşturmak için gerekli SQL komutlarını içerir. Migrasyon dosyasını inceledikten sonra, değişiklikleri veritabanına uygulamak için Serverpod sunucunuzu yeniden başlatmanız yeterlidir. Sunucu başlangıcında, yeni migrasyonları otomatik olarak algılayacak ve uygulayacaktır. Eğer halihazırda çalışıyorsa, sunucuyu kapatıp tekrar başlatın (Ctrl+C ile kapatıp dart bin/main.dart ile tekrar başlatın).
Veritabanı İşlemleri (CRUD)
Şimdi bir Todo öğesini veritabanına kaydetmek ve ardından okumak için bir API endpoint'i oluşturalım. my_serverpod_project_server/lib/src/endpoints/todo_endpoint.dart adında yeni bir dosya oluşturalım:
// my_serverpod_project_server/lib/src/endpoints/todo_endpoint.dart
import 'package:serverpod/serverpod.dart';
import '../generated/protocol.dart';
class TodoEndpoint extends Endpoint {
Future createTodo(Session session, Todo todo) async {
await Todo.db.insert(session, todo);
}
Future> getTodos(Session session) async {
return await Todo.db.find(session);
}
Future updateTodo(Session session, Todo todo) async {
await Todo.db.update(session, todo);
}
Future deleteTodo(Session session, int id) async {
await Todo.db.deleteRow(session, where: (t) => t.id.equals(id));
}
}
Bu endpoint, createTodo, getTodos, updateTodo ve deleteTodo metodlarını içerir. Bu metodlar, Serverpod'un ORM'ini kullanarak Todo nesnelerini veritabanına ekler, sorgular, günceller ve siler. Dikkat ederseniz, Todo.db statik erişim noktası üzerinden tüm bu veritabanı işlemlerini kolayca yapabiliyoruz.
Bu yeni endpoint'i ekledikten sonra, client kodunun güncellenmesi için tekrar ana dizinde serverpod generate komutunu çalıştırmayı ve ardından sunucuyu yeniden başlatmayı unutmayın. Daha sonra Flutter uygulamanızdan bu endpoint'leri çağırarak bir To-Do listesi uygulaması geliştirebilirsiniz. Bu, Serverpod'un veritabanı entegrasyonuyla full-stack geliştirmenin ne kadar akıcı hale geldiğinin güzel bir örneğidir.
Vaka Analizi: Basit Bir To-Do Uygulaması Nasıl Geliştirilir?
Şimdiye kadar Serverpod'un temel kurulumunu, API endpoint'i oluşturmayı ve veritabanı ile nasıl entegre olunduğunu öğrendik. Bu bilgileri kullanarak, gerçek dünya senaryosuna yakın, basit bir "Yapılacaklar Listesi" (To-Do) uygulaması geliştirelim. Bu vaka analizi, hem Serverpod backend'inin hem de Flutter frontend'inin nasıl bir araya geldiğini uygulamalı olarak gösterecektir.
Gereksinimler
Uygulamamızın temel gereksinimleri şunlardır:
- Yeni yapılacaklar ekleyebilme.
- Var olan yapılacakları listeleyebilme.
- Yapılacakların tamamlanma durumunu değiştirebilme.
- Yapılacakları silebilme.
Serverpod Backend Geliştirme
Önceki bölümde Todo modelimizi ve TodoEndpoint'imizi oluşturmuştuk. Bu endpoint, createTodo, getTodos, updateTodo ve deleteTodo metodlarını zaten içeriyor. Bu, To-Do uygulamamızın temel backend ihtiyaçlarını karşılamak için yeterli olacaktır. Eğer henüz oluşturmadıysanız, önceki bölümdeki adımları takip ederek todo.yaml modelini ve todo_endpoint.dart dosyasını oluşturup serverpod generate ve serverpod create-migration komutlarını çalıştırdığınızdan emin olun.
// my_serverpod_project_server/lib/src/endpoints/todo_endpoint.dart içeriği
import 'package:serverpod/serverpod.dart';
import '../generated/protocol.dart';
class TodoEndpoint extends Endpoint {
Future createTodo(Session session, Todo todo) async {
await Todo.db.insert(session, todo);
}
Future> getTodos(Session session) async {
return await Todo.db.find(session, orderBy: (t) => t.id); // ID'ye göre sırala
}
Future updateTodo(Session session, Todo todo) async {
await Todo.db.update(session, todo);
}
Future deleteTodo(Session session, int id) async {
await Todo.db.deleteRow(session, where: (t) => t.id.equals(id));
}
}
Serverpod sunucunuzun çalıştığından emin olun (my_serverpod_project_server dizininde dart bin/main.dart).
Flutter Frontend Geliştirme
Şimdi my_serverpod_project_flutter dizinindeki Flutter uygulamamızı güncelleyelim. lib/main.dart dosyasını açın ve aşağıdaki kodla değiştirin. Bu kod, Serverpod client'ını kullanarak backend'deki To-Do endpoint'leri ile etkileşim kuran basit bir UI oluşturacaktır.
// my_serverpod_project_flutter/lib/main.dart
import 'package:flutter/material.dart';
import 'package:my_serverpod_project_client/my_serverpod_project_client.dart';
import 'package:serverpod_flutter/serverpod_flutter.dart';
var client = Client(
'http://localhost:8080/', // Sunucunuzun adresini ve portunu ayarlayın
)
..connectivityMonitor = ServerpodConnectivityMonitor();
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Serverpod Todo App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const TodoListPage(),
);
}
}
class TodoListPage extends StatefulWidget {
const TodoListPage({Key? key}) : super(key: key);
@override
State createState() => _TodoListPageState();
}
class _TodoListPageState extends State {
final TextEditingController _todoController = TextEditingController();
List _todos = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
_fetchTodos();
}
Future _fetchTodos() async {
try {
setState(() { _isLoading = true; });
final fetchedTodos = await client.todo.getTodos();
setState(() {
_todos = fetchedTodos;
});
} catch (e) {
debugPrint('Error fetching todos: $e');
} finally {
setState(() { _isLoading = false; });
}
}
Future _addTodo() async {
if (_todoController.text.isEmpty) return;
try {
final newTodo = Todo(description: _todoController.text, isCompleted: false);
await client.todo.createTodo(newTodo);
_todoController.clear();
await _fetchTodos(); // Listeyi güncelle
} catch (e) {
debugPrint('Error adding todo: $e');
}
}
Future _toggleTodoStatus(Todo todo) async {
try {
final updatedTodo = todo.copyWith(isCompleted: !todo.isCompleted);
await client.todo.updateTodo(updatedTodo);
await _fetchTodos(); // Listeyi güncelle
} catch (e) {
debugPrint('Error toggling todo status: $e');
}
}
Future _deleteTodo(int id) async {
try {
await client.todo.deleteTodo(id);
await _fetchTodos(); // Listeyi güncelle
} catch (e) {
debugPrint('Error deleting todo: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Serverpod Todo App'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _todoController,
decoration: const InputDecoration(
labelText: 'Yeni görev ekle',
border: OutlineInputBorder(),
),
onSubmitted: (_) => _addTodo(),
),
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: _addTodo,
child: const Text('Ekle'),
),
],
),
),
_isLoading
? const CircularProgressIndicator()
: Expanded(
child: ListView.builder(
itemCount: _todos.length,
itemBuilder: (context, index) {
final todo = _todos[index];
return ListTile(
title: Text(
todo.description,
style: TextStyle(
decoration: todo.isCompleted ? TextDecoration.lineThrough : null,
),
),
leading: Checkbox(
value: todo.isCompleted,
onChanged: (_) => _toggleTodoStatus(todo),
),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () => _deleteTodo(todo.id!),
),
);
},
),
),
],
),
);
}
}
Uygulamayı Çalıştırma ve Test Etme
Bu kodu main.dart dosyanıza yapıştırdıktan sonra, Flutter uygulamasını bir emülatörde, fiziksel bir cihazda veya web tarayıcısında çalıştırabilirsiniz:
cd my_serverpod_project/my_serverpod_project_flutter
flutter run
Uygulama başladığında, bir giriş alanı ve ekle butonu ile karşılaşacaksınız. Yeni görevler ekleyebilir, checkbox'ları işaretleyerek tamamlanma durumlarını değiştirebilir ve çöp kutusu simgelerine basarak görevleri silebilirsiniz. Tüm bu işlemler, Serverpod backend'inizle etkileşim kurarak gerçekleştirilecektir. Herhangi bir değişiklik yaptığınızda (ekleme, güncelleme, silme), liste anında güncellenecektir.
Bu basit To-Do uygulaması, Serverpod ve Flutter'ın full-stack geliştirme için ne kadar güçlü ve entegre bir çözüm sunduğunu açıkça göstermektedir. Tip güvenli API çağrıları, otomatik veritabanı eşleşmeleri ve tek bir dil kullanımı, geliştirme sürecini önemli ölçüde hızlandırır ve hataları azaltır. Bu vaka analizi, kendi full-stack mobil uygulamalarınızı geliştirmek için sağlam bir temel sunmaktadır.
İleri Düzey İpuçları ve En İyi Uygulamalar: Serverpod ile Uygulamanızı Güçlendirin
Serverpod kurulumunu ve temel bir full-stack uygulamanın nasıl geliştirildiğini öğrendik. Ancak Serverpod'un sunduğu imkanlar bunlarla sınırlı değil. Uygulamanızın performansını artırmak, güvenliğini sağlamak ve daha karmaşık özellikler eklemek için bilmeniz gereken bazı ileri düzey ipuçları ve en iyi uygulamalar bulunmaktadır. Bu bölümde, deneyimli geliştiricilerin Serverpod'dan daha fazla verim almasına yardımcı olacak stratejileri ele alacağız.
Kimlik Doğrulama ve Güvenlik
Hemen hemen her modern uygulama, kullanıcı kimlik doğrulamasına ihtiyaç duyar. Serverpod, yerleşik olarak kimlik doğrulama (authentication) özelliklerini destekler. Kullanıcı hesapları oluşturma, oturum açma, JWT (JSON Web Token) tabanlı token yönetimi gibi konuları Serverpod'un kendi modülleriyle kolayca halledebilirsiniz. Örneğin, serverpod_auth_server ve serverpod_auth_flutter paketleri, bu süreci basitleştirir. Güvenli API endpoint'leri oluştururken, session.authenticated veya belirli roller için yetkilendirme kontrolleri eklemeyi unutmayın. API endpoint'lerinizi varsayılan olarak herkese açık bırakmak yerine, hassas verilere erişimi kısıtlamak için kimlik doğrulama mekanizmalarını aktif olarak kullanmalısınız.
// Örnek: Yalnızca oturum açmış kullanıcıların erişebileceği bir endpoint
class SecureEndpoint extends Endpoint {
@override
bool get requireAuthentication => true; // Bu endpoint için kimlik doğrulama gerekli
Future getSecretData(Session session) async {
// session.userInfo ile oturum açmış kullanıcının bilgilerine erişilebilir
final userId = session.auth.userId;
return 'Gizli veriye erişildi, kullanıcı ID: $userId';
}
}
Performans Optimizasyonu ve Önbellekleme (Caching)
Yüksek performanslı uygulamalar geliştirmek için önbellekleme hayati öneme sahiptir. Serverpod, Redis entegrasyonu sayesinde kolayca önbellekleme stratejileri uygulamanıza olanak tanır. Sıkça erişilen ancak nadiren değişen verileri Redis'te saklayarak veritabanı yükünü azaltabilir ve yanıt sürelerini önemli ölçüde kısaltabilirsiniz. Serverpod'un ORM'i ile yapacağınız sorgularda, session.serverpod.redis üzerinden doğrudan Redis'e erişebilir veya özel önbellekleme mantığınızı uygulayabilirsiniz.
Hata Ayıklama ve Loglama
Geliştirme sürecinde hatalarla karşılaşmak kaçınılmazdır. Serverpod, Dart'ın güçlü hata ayıklama yeteneklerinden faydalanır. VS Code veya IntelliJ IDEA gibi IDE'ler üzerinden kolayca breakpoint'ler ekleyebilir ve kodunuzu adım adım takip edebilirsiniz. Ayrıca, Serverpod yerleşik olarak loglama mekanizmalarına sahiptir. debugPrint, print veya daha gelişmiş loglama kütüphaneleri kullanarak sunucu tarafındaki olayları izleyebilirsiniz. Üretim ortamında, yapılandırılmış loglama (örneğin, ELK Stack ile) hata tespiti ve performans izleme için kritik öneme sahiptir.
Deployment Stratejileri
Uygulamanızı geliştirdikten sonra, onu canlıya almak (deployment) önemlidir. Serverpod, konteyner tabanlı bir mimariye sahip olduğu için Docker ve Kubernetes gibi araçlarla uyumludur. Uygulamanızı bir bulut sağlayıcısına (AWS, Google Cloud, Azure) dağıtırken, Docker image'ınızı oluşturabilir ve Kubernetes kümelerinde ölçeklenebilir bir şekilde çalıştırabilirsiniz. Serverpod'un resmi dökümantasyonunda dağıtım stratejileri hakkında detaylı bilgiler bulabilirsiniz. CI/CD (Sürekli Entegrasyon/Sürekli Teslimat) boru hatları kurarak, kod değişikliklerini otomatik olarak test edip dağıtarak geliştirme sürecinizi otomatikleştirmek, modern geliştirmenin ayrılmaz bir parçasıdır.
Mobil Uyumluluk ve Duyarlı Tasarım (Contextual Reminder)
Serverpod bir backend çözümü olmasına rağmen, Flutter ile full-stack mobil geliştirmenin bir parçası olduğu için mobil uyumluluk ve duyarlı tasarım prensiplerini hatırlatmak önemlidir. Flutter, tek bir kod tabanıyla farklı ekran boyutlarına ve cihazlara uyum sağlayabilen kullanıcı arayüzleri oluşturmanızı zaten sağlar. Serverpod ise bu duyarlı arayüzlerin arkasındaki hızlı ve ölçeklenebilir veri akışını garantiler. Backend tarafından gönderilen verilerin, farklı mobil cihazlarda doğru şekilde işlenmesi ve sunulması için frontend tasarımınızın esnek olması gerektiğini unutmayın. Bu, Serverpod'un sağladığı hızlı veri alışverişiyle birleştiğinde, her boyuttaki ekranda mükemmel bir kullanıcı deneyimi sunar.
Bu ileri düzey ipuçları, Serverpod ile geliştirdiğiniz uygulamaların daha sağlam, daha güvenli ve daha performanslı olmasını sağlayacaktır. Unutmayın ki, iyi bir uygulamanın temeli, sadece çalışan kod değil, aynı zamanda en iyi uygulamaları takip eden ve ölçeklenebilir bir mimariye sahip olan koddur. Serverpod, bu hedeflere ulaşmanız için güçlü bir temel sunar.
Sonuç ve Sıkça Sorulan Sorular
Bu kapsamlı makalede, full-stack mobil geliştirmenin Flutter ve Serverpod ile nasıl daha kolay, daha verimli ve daha keyifli hale geldiğini detaylıca inceledik. Serverpod'un kurulumundan temel API endpoint'i oluşturmaya, veritabanı entegrasyonundan gerçek dünya bir To-Do uygulaması geliştirmeye kadar birçok konuyu adım adım ele aldık. Ayrıca, uygulamanızı daha güçlü ve güvenli hale getirecek ileri düzey ipuçları ve en iyi uygulamaları da paylaştık. Serverpod'un Dart tabanlı olması, tip güvenliği sağlaması ve otomatik kod jenerasyonu gibi özellikleri sayesinde, geliştiriciler backend karmaşıklıklarıyla daha az uğraşarak kullanıcı deneyimine ve iş mantığına odaklanabiliyor.
Flutter ve Serverpod kombinasyonu, modern mobil uygulama geliştiricileri için gerçekten dönüştürücü bir potansiyel sunuyor. Tek bir dilde (Dart) hem frontend hem de backend geliştirebilme yeteneği, geliştirme sürecini hızlandırır, hata oranlarını azaltır ve ekip içindeki iş birliğini artırır. Performans, ölçeklenebilirlik ve yerleşik özellikler (kimlik doğrulama, WebSocket, ORM) ile Serverpod, küçük prototiplerden büyük ölçekli kurumsal uygulamalara kadar her türlü projeye uygun bir backend çözümüdür. Bu makalenin, Serverpod ile full-stack mobil geliştirme yolculuğunuza sağlam bir başlangıç yapmanız için size gerekli bilgi ve güveni verdiğini umuyoruz.
Sıkça Sorulan Sorular
-
Serverpod ücretsiz mi?
Evet, Serverpod açık kaynaklı bir projedir ve MIT lisansı altında ücretsiz olarak kullanılabilir. Hem geliştirme hem de üretim ortamlarında hiçbir ücret ödemeden kullanabilirsiniz.
-
Serverpod hangi veritabanını kullanıyor?
Serverpod, varsayılan olarak PostgreSQL veritabanını kullanır. Geliştirme ortamında Docker aracılığıyla kolayca bir PostgreSQL konteyneri kurar ve yönetir.
-
Serverpod sadece Flutter ile mi çalışır?
Serverpod, Flutter uygulamalarıyla mükemmel bir uyum içinde çalışmak üzere tasarlanmıştır ve client kodunu Dart olarak generate eder. Teorik olarak, generate edilen client kodunu Dart destekleyen diğer platformlarda da kullanmak mümkün olsa da, esasen Flutter için optimize edilmiştir. Başka bir teknolojiyle kullanmak için manuel entegrasyon veya özel client yazmanız gerekebilir.
-
Serverpod'u üretim ortamında kullanabilir miyim?
Evet, Serverpod üretim ortamında kullanılmak üzere tasarlanmıştır. Yüksek performans, ölçeklenebilirlik ve güvenlik özellikleri sunar. Docker ve Kubernetes ile kolayca dağıtılabilir.
-
Serverpod ile gerçek zamanlı uygulamalar geliştirebilir miyim?
Evet, Serverpod yerleşik olarak WebSocket desteği sunar. Bu sayede sohbet uygulamaları, canlı bildirimler veya gerçek zamanlı veri senkronizasyonu gibi interaktif ve gerçek zamanlı özelliklere sahip uygulamalar geliştirebilirsiniz.