Orion ailesini neden yaptım
.NET backend'lerinin çoğu sonunda aynı düzine şeye ihtiyaç duyuyor: validation, distributed lock, audit kaydı, outbox, şifreli kolonlar, tipli ID'ler, idempotent endpoint'ler, rate limit, retry. Her ekip bunları yeniden yazıyor; her seferinde biraz farklı, her biri kendince biraz hatalı.
Orion ailesi buna benim cevabım: bu problemlerin her biri için küçük, odaklı, tek bir kalite çıtasıyla yazılmış ve NuGet'te yayınlanmış kütüphaneler.
Bugün 89 paket altında 24 kütüphane var ve 350 binden fazla kez indirildiler. Bu yazı neden var olduklarını, onları neyin bir arada tuttuğunu ve her birinin ne işe yaradığını anlatıyor.
Framework değil, yapı taşı
Her Orion kütüphanesi tek bir problemi çözüyor ve kendi başına kullanılabiliyor. OrionLock'u bir lock'a ihtiyacınız olduğu için eklersiniz, bir platforma üye olduğunuz için değil. Aralarında derin bir bağımlılık ağı yok; sadece ihtiyacınız olanı alırsınız.
Bu, bazen "hayır" demek anlamına da geliyor. OrionPatch bir transactional outbox; dokümanı saga'ların kapsam dışında olduğunu açıkça söylüyor: bir process manager'a ihtiyacınız varsa MassTransit ya da Wolverine'e bakın. Nerede durduğunu bilen bir kütüphaneye, her şey olmak isteyen bir kütüphaneden daha kolay güvenilir.
Aileyi bir arada tutan şey
Kütüphaneleri birbiri ardına yazarken beş şeyin tekrar tekrar yazıldığını ve her seferinde birbirinden uzaklaştığını fark ettim:
- observer'ları güvenli çağırmak; gözlemlenebilirlik tarafındaki bir arıza asıl işi yapan kodu asla bozmasın diye,
- OpenTelemetry isimlendirmesi; her kütüphanenin trace ve metrikleri dashboard'da aynı görünsün diye,
- testlerin kontrol edebildiği bir saat,
- options ve DI kaydının şekli,
- hataların ortak dili.
Bunlar artık tek bir yerde, Orion.Abstractions içinde yaşıyor. Yüzeyi 1.0'da donduruldu: bütün
sözleşmeler 1.x boyunca kaynak ve binary olarak uyumlu kalıyor; bir kütüphane, kardeşinin güncellemesiyle
kırılmıyor. Bunlara eşlik eden kurallar yazılı ve ailedeki her paket için geçerli.
Bu omurgadan iki kütüphane doğdu. OrionClock bir TimeProvider; onu kabul eden her .NET API'sine
doğrudan takılıyor ve testlerin beklemek yerine zamanı ileri sarmasını sağlıyor. OrionResult beklenen
hatalara bir şekil veriyor: sıfır allocation'lı bir Result<T>, bir Option<T> ve kodu, türü ve alan
hataları olan yapılandırılmış bir Error.
Ailede neler var?
Girdi ve domain
- OrionGuard: validation, guard clause'lar ve DDD yapı taşları; ASP.NET Core, MediatR, Blazor, gRPC, SignalR ve OpenTelemetry entegrasyonları, source generator'lar ve 14 dilde hata mesajları. Ailenin en çok kullanılanı.
- OrionKey: tek bir attribute ile tipli ID'ler; eşitlik, EF Core ve JSON dönüştürücüleri sizin için üretiliyor.
Veri
- OrionAudit: JSON Patch farklarıyla otomatik EF Core audit kaydı ve bir entity'yi herhangi bir andaki hâliyle yeniden kurmak için zamanda yolculuk.
- OrionVault: EF Core için kolon seviyesinde şifreleme: AES-256-GCM, anahtar rotasyonu ve şifreli değerlerde arama yapmak için blind index.
- OrionPage: 10.000. sayfada bile hızlı kalan keyset pagination; çünkü
OFFSETbir tablo taraması.
Mesajlaşma ve tutarlılık
- OrionPatch ve OrionInbox: güvenilir mesajlaşmanın iki yarısı. Aynı
SaveChangestransaction'ı içinde kuyruğa al, en az bir kez gönder; karşı tarafta her mesajın etkisini tam bir kez uygula. - OrionSaga: süreç içi saga orkestrasyonu; bir adım başarısız olursa tamamlanan adımlar geri alınıyor.
- OrionRelay: HMAC-SHA256 ile imzalanan, backoff ve jitter ile yeniden denenen giden webhook'lar.
Koordinasyon
- OrionLock: Redis, Postgres, SQL Server ya da EF Core üzerinde, lease yenilemeli ve fencing token'lı distributed lock'lar.
- OrionBeacon: leader election; bir kez çalışması gereken işi tam olarak bir instance çalıştırsın diye.
HTTP ve API'ler
- OrionOnce: idempotency key'ler; yeniden denenen bir istek iki kez çalışmak yerine saklanan cevabı alıyor.
- OrionEnvelope: bütün API için tek bir HTTP sözleşmesi: başarıda tipli
{ data, meta }, hatada RFC 9457 problem details. - OrionRate: token-bucket ve sliding-window rate limiting.
- OrionGrant ve OrionLedger: izinler ve politikalar; API key'lerin bütün yaşam döngüsü.
- OrionStream: sınırlı buffer'lar ve heartbeat'lerle Server-Sent Events.
Her yerde işe yarayanlar
- OrionLens bir correlation id'yi async çağrılar ve HTTP boyunca taşıyor; OrionShade secret'ları ve kişisel verileri log'a ulaşmadan maskeliyor; OrionCache stampede yaşatmadan cache-aside yapıyor; OrionResilience OrionClock üzerinden jitter'lı retry yapıyor, böylece bir retry testi hiç zaman almıyor.
Hepsi bir arada
Paket sayfaları kütüphaneleri tek tek gösteriyor. OrionShowcase ise birlikte nasıl çalıştıklarını gösteriyor: tek bir para transferinin OrionGuard'ın validation'ından, OrionLock'un distributed lock'larından, OrionAudit'in değişiklik kaydından, OrionPatch'in outbox'ından, OrionKey'in tipli ID'lerinden ve OrionVault'un şifreli kişisel verilerinden geçtiği, production'a benzeyen bir bankacılık örneği. Bu bütünü kurmak, tek bir paketin göründüğünden çok daha zor; örneğin bütün amacı bu.
Neden paylaşıyorum?
Bunları ihtiyacım olduğu için yazdım; yayınlıyorum ki kimse onları yeniden yazmak zorunda kalmasın. Her kütüphane MIT lisanslı, dokümantasyonu bu sitede ve issue'lar GitHub'da açık. Veritabanı ya da mesaj kuyruğu gerektirmeyenleri doğrudan buradaki playground'da deneyebilirsiniz.
Birini kullanıyorsanız ya da denediniz ve işinize yaramadıysa, nedenini bilmek isterim. Birinin bana söyleyebileceği en faydalı şey bu.
