Mert Özen Her Satırda Daha İleri

Blog

Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.

Seriler
15 yazı bulundu
Bookstore'u Microservice'lere Bölmek: Hedef Mimari, Service Listesi ve Bu Serinin Kuralları
Backend SERİ 01

Bookstore'u Microservice'lere Bölmek: Hedef Mimari, Service Listesi ve Bu Serinin Kuralları

Bookstore'u beş service'e bölüyoruz: Catalog, Ordering, Inventory, Payments ve Notifications; her biri kendi veritabanına sahip, service'ler arasında kimlik ISBN ve Guid, paylaşılan kod yalnız contract'lar ve ServiceDefaults. Yazı hedef mimariyi, hangi kenarın sync hangisinin async olduğunu, Aspire, YARP, RabbitMQ, WolverineFx ve Keycloak kararlarının gerekçesini ve bu kuralı CI'da koruyan architecture test'ini gerçek çıktılarla gösteriyor.

14 Kas 2026 14 dk 3
Solution İskeleti: Aspire AppHost, ServiceDefaults ve Tek Komutla Lokal Ortam
Backend SERİ 02

Solution İskeleti: Aspire AppHost, ServiceDefaults ve Tek Komutla Lokal Ortam

Aspire AppHost, Bookstore'un beş service'ini, service başına bir SQL Server database'ini, Redis'i, RabbitMQ'yu ve Keycloak'u tek C# dosyasında tarif edip tek komutla çalıştırıyor; ServiceDefaults telemetri, health check, service discovery ve resilience'ı her service'e tek satırla ekliyor. Migration'ları service binary'sini --migrate ile ayrı bir resource olarak çalıştırıp WaitForCompletion ile bekliyoruz; WaitFor'un neden yetmediğini gerçek başlama saatleriyle gösteriyoruz.

14 Kas 2026 14 dk 2
Catalog Service: Kendi Veritabanı, REST API ve Okuma Ağırlıklı Optimizasyonlar
Backend SERİ 03

Catalog Service: Kendi Veritabanı, REST API ve Okuma Ağırlıklı Optimizasyonlar

Catalog service'i kendi veritabanının sahibi olan, okuma trafiğine göre ayarlanmış bir service'e dönüştürüyoruz: AsNoTracking projection ile arama ve sayfalama, Redis'te paylaşılan output cache ve tag ile eviction, URL segment versioning, ProblemDetails ve oasdiff ile denetlenen OpenAPI contract'ı. Fiyat ve isim değişiklikleri versiyonlu BookPriceChanged ve BookRenamed event'lerine dönüşüyor; aynı versiyon concurrency token olarak 8 paralel isteğin 4'ünü 409 ile durduruyor.

14 Kas 2026 13 dk 2
Ordering Service: Zengin Domain Model, Kendi Veritabanı ve Sipariş API'si
Backend SERİ 04

Ordering Service: Zengin Domain Model, Kendi Veritabanı ve Sipariş API'si

Ordering, Order aggregate'ini kendi veritabanında tutuyor, kitapların başlık ve fiyatını Catalog'a sormak yerine bir kez doldurulan yerel kopyasından okuyor ve müşterinin sepette gördüğü fiyat kopyayla tutmazsa siparişi 409 ile reddediyor. Catalog kapalıyken bile sipariş 201 ile oluşuyor; Guid v7'nin SQL Server'daki sırası, non-clustered primary key ve sipariş listesi için projection gerçek çıktılarla gösteriliyor.

14 Kas 2026 14 dk 6
Inventory Service ve gRPC ile Sync İletişim: Stok Rezervasyonu, Deadline ve Resilience
Backend SERİ 05

Inventory Service ve gRPC ile Sync İletişim: Stok Rezervasyonu, Deadline ve Resilience

Ordering, stok rezervasyonu için Inventory'yi 2 saniyelik deadline'lı bir gRPC çağrısıyla kullanıyor; rezervasyon sipariş id'siyle idempotent, rowversion ile optimistic concurrency'li ve 15 dakikalık TTL ile kendiliğinden serbest kalıyor. Yazı 20 paralel siparişte çakışmaları, deadline'ın sunucudaki işi iptal etmesini, cleartext HTTP/2 tuzağını, buf ile breaking change kontrolünü ve Inventory kapalıyken checkout'un bedelini gerçek çıktılarla gösteriyor.

14 Kas 2026 17 dk 6
Integration Event'leri ile Async İletişim: RabbitMQ, Messaging Library ve Transactional Outbox
Backend SERİ 06

Integration Event'leri ile Async İletişim: RabbitMQ, Messaging Library ve Transactional Outbox

Catalog ve Ordering, integration event'leri WolverineFx'in EF Core outbox'ı ile kendi veritabanlarına yazıp commit'ten sonra RabbitMQ'ya gönderiyor; RabbitMQ kapalıyken bile fiyat değişikliği 204 dönüyor ve event broker geri geldiğinde Ordering'e ulaşıyor. Ordering'in durable inbox'ı tekrar eden mesajı, alan başına versiyon da geç gelen eski event'i eliyor; poison message'lar service'in kendi dead letter queue'suna exception bilgisiyle düşüyor.

14 Kas 2026 13 dk 5
Checkout Saga'sı: Orchestration ile Sipariş, Stok, Ödeme ve Compensation
Backend SERİ 07

Checkout Saga'sı: Orchestration ile Sipariş, Stok, Ödeme ve Compensation

Checkout'un sahibi Ordering'deki bir Wolverine saga'sı: stoğu ve ödemeyi mesajlarla istiyor, ödeme reddinde ya da 15 dakikalık timeout'ta stoğu serbest bırakıp siparişi iptal ediyor, iptal edilmiş siparişe geç gelen ödemeyi iadeye çeviriyor. Sipariş artık 202 ile kabul ediliyor; Inventory kapalıyken bile 23 ms'de cevap veriyor ve Inventory dönünce onaylanıyor. Saga'nın adımları veritabanısız unit testlerle doğrulanıyor.

14 Kas 2026 12 dk 6
Payments Service: Fake Ödeme Sağlayıcısı, Idempotent Charge ve Webhook Callback'i
Backend SERİ 08

Payments Service: Fake Ödeme Sağlayıcısı, Idempotent Charge ve Webhook Callback'i

Payments, ödeme sağlayıcısına siparişten türetilen bir Idempotency-Key ile charge gönderiyor, POST'u HTTP katmanında tekrar etmiyor ve zaman aşımını başarısızlık değil bilinmeyen sonuç sayıyor; sonucu imzalı ve replay korumalı bir webhook ya da reconciliation job'ı belirliyor. Sağlayıcının modeli bir anti-corruption layer'da kalıyor; iptal edilmiş siparişe geç gelen ödeme uçtan uca iadeye dönüşüyor.

14 Kas 2026 10 dk 7
API Gateway ve BFF: YARP ile Angular İçin Tek Giriş Noktası ve Aggregation
Backend SERİ 09

API Gateway ve BFF: YARP ile Angular İçin Tek Giriş Noktası ve Aggregation

Bookstore.Bff, YARP ile Angular'ın tek giriş noktası oluyor: service discovery ile çözülen proxy route'ları, iç adresi sızdıran Location header'ının çevrilmesi ve sipariş route'unda rate limit. Kitap sayfası Catalog ve Inventory'yi paralel çağıran bir aggregation endpoint'inden geliyor; Inventory kapalıyken sayfa stoksuz 533 ms'de, Catalog kapalıyken 30 saniyelik bir 500 yerine 2 saniyede 503 dönüyor.

14 Kas 2026 9 dk 6
Authentication ve Service-to-Service Güven: Keycloak, BFF Session'ı, Token Propagation ve Client Credentials
Backend SERİ 10

Authentication ve Service-to-Service Güven: Keycloak, BFF Session'ı, Token Propagation ve Client Credentials

Keycloak realm'i secret'sız bir JSON'dan import ediliyor; BFF kullanıcıyı OIDC ile giriş yaptırıp token'ları HttpOnly cookie oturumunda tutuyor, sipariş route'larında kullanıcının access token'ını Ordering'e taşıyor ve stok sorgusu için kendi client credentials token'ını kullanıyor. Her service token'ı audience ve rol ile kendisi doğruluyor; Inventory için alınmış bir token Ordering'de 401 alıyor ve kimlik event'lere token değil CustomerId olarak giriyor.

14 Kas 2026 11 dk 5
Angular Frontend: Eventual Consistency'yi UI'da Yönetmek ve Sipariş Durumunu Canlı Göstermek
Backend SERİ 11

Angular Frontend: Eventual Consistency'yi UI'da Yönetmek ve Sipariş Durumunu Canlı Göstermek

Sipariş 202 ile kabul edildiğinde UI "onaylandı" değil "onay bekleniyor" demeli; durum değişikliği Notifications'tan SignalR ile push edilir ama sayfa siparişi her push'ta Ordering'den yeniden okur. Angular 22 uygulaması BFF'nin arkasında tek origin'den sunuluyor; push'un POST cevabından önce gelmesi, Notifications kapalıyken polling'e düşmek, Redis ile tek seferlik e-posta ve stok, ödeme ve fiyat hataları gerçek tarayıcıda denendi.

14 Kas 2026 14 dk 6
Distributed Tracing ve Observability: Bir Siparişi Angular'dan RabbitMQ'ya Kadar İzlemek
Backend SERİ 12

Distributed Tracing ve Observability: Bir Siparişi Angular'dan RabbitMQ'ya Kadar İzlemek

Bir siparişi uçtan uca tek trace'te görmek için ServiceDefaults'a Wolverine'in ActivitySource'u ve gRPC client instrumentation'ı eklenmeli; trace context mesajın parent-id header'ında taşınıyor. Önce iki service'te biten trace eklemeden sonra 81 span ve beş service oldu; checkout'un 1,15 saniyesinin çoğu ödeme sağlayıcısında, reconciliation'da trace kopuyor ve sipariş/ödeme metric'leri IMeterFactory ile ölçülüyor.

14 Kas 2026 11 dk 8
Blog Haritası