Skip to main content
API tek bir .NET 10 projesidir: src/DiyanetCleanArchitecture.API. Tüm servis kayıtları ve HTTP pipeline’ı Program.cs içinde elle (minimal API host) kurulur. Bu sayfa kayıt sırasını ve middleware sırasını birebir gösterir — her ikisi de kritiktir, sıra bozulursa uygulama sessizce yanlış çalışır.

Servis kayıt sırası (builder.Services)

Program.Main içinde servisler şu sırayla kaydedilir. Sıra, bazı bileşenler için zorunludur (aşağıda işaretli).
// ── Layer Registration ──────────────────────────────────────
builder.Services.AddHangfireServers(builder.Configuration);
builder.Services.AddInfrastructureEFCore(builder.Configuration);   // DbContext, repository, interceptor, MassTransit Outbox
builder.Services.AddSmsService(builder.Configuration);             // OtpSmsService (NetGSM)
builder.Services.AddEmailService(builder.Configuration);           // EmailService (MailKit + Scriban)
builder.Services.AddAuthenticatorService(builder.Configuration);   // TOTP (OtpNet)
builder.Services.AddOAuthProviders(builder.Configuration);         // Google / Meta / Keycloak OAuth
builder.Services.AddNotificationService(builder.Configuration);    // SSE admin notification broadcaster
builder.AddApplication();                                          // MediatR + pipeline behavior'lar + AutoMapper

// ── Building Blocks ─────────────────────────────────────────
builder.Services.AddJwt(builder.Configuration);                    // BB.Jwt — uygulamanın kendi JWT scheme'i
builder.Services.AddDeviceDetector(builder.Configuration);

builder.Services.AddRedisCache(builder.Configuration);             // ① IDistributedCache (Redis)
builder.Services.AddCache(builder.Configuration);                  // ② IHybridRequestCache abstraction
builder.Services.AddHybridCache(/* L1 + L2 TTL */);                // ③ HybridCache (L1 memory + L2 Redis)

builder.Services.AddKeycloak(builder.Configuration);               // İki Keycloak JWT Bearer scheme (Vatandas + Personel)
builder.Services.AddKeycloakProvisioning(builder.Configuration);   // IHostedService — realm/client/user otomatik kurar
builder.Services.AddKeycloakExternalLoginProvisioning();           // OnTokenValidated → davetli kullanıcı aktivasyonu

builder.Services.AddDiyanetObservability(builder.Configuration);   // OTel + Prometheus (opt-in)
Cache kayıt sırası kritik. AddRedisCache (IDistributedCache) mutlaka AddHybridCache’ten önce gelmelidir. HybridCache kayıt anında bir IDistributedCache bulamazsa kalıcı olarak L1-only (memory) moduna düşer ve sonradan eklenen Redis’i hiç görmez — yani Redis’e hiçbir zaman yazmaz.
Bu blokların ardından RBAC, CORS ve sunum servisleri gelir:
  • RBAC AuthorizationDynamicPermissionPolicyProvider (singleton), PermissionAuthorizationHandler, ScopeAuthorizationHandler, ActiveAccountAuthorizationHandler; ICurrentUser / ICurrentCitizen / ICurrentTenant / ICurrentActor; ApiCompositeClaimsTransformation. Üç named policy: PersonelAuthenticated, VatandasAuthenticated, AnyKeycloakAuthenticated.
  • CORS — beş policy: AllowedBackofficePolicy, AllowedPublicPolicy, AllowedWebsitePolicy, AllowedDiyanetCleanArchitectureAPIPolicy, AllowAll. Origin’ler AllowedCorsOrigins:* config’inden okunur (yoksa exception fırlatılır).
  • AddControllers() (camelCase JSON), AddOutputCache(), ProblemDetails (Hellang), NSwag (AddOpenApiDocument), RequestLocalization (tr-TR).

Middleware pipeline sırası (app)

app.UseHttpsRedirection();
app.UseStaticFiles();                  // wwwroot/uploads/* — duyuru kapak görselleri
app.UseProblemDetails();               // RFC 7807 — exception → ProblemDetails
app.UseSerilogRequestLoggingMiddleware();
app.UseRequestLocalization(/* tr-TR default */);
app.UseRouting();
app.UseCors(/* Prod/Stage: Backoffice · Dev: AllowAll */);
app.UseAuthentication();
app.UseTokenVersionValidation();       // Feature flag: Security:TokenVersionValidation — RBAC invalidation
app.UseAuthorization();
app.UseHangfireDashboard(/* /jobs */);
app.UseOutputCache();
app.MapControllers();
app.MapHealthCheckEndpoints();         // /health/live, /health/ready, /health/external, /health/startup, /health
app.MapDiyanetObservabilityEndpoints();// /metrics (Observability:Enabled=true ise)
// Dev/Stage: MapOpenApi + Swagger UI + Scalar · Prod: Scalar (RequireAuthorization)
UseProblemDetails Routing’den önce çağrılır — pipeline’ın herhangi bir yerinde oluşan exception’lar yakalanır. UseTokenVersionValidation Authentication ile Authorization arasına girer: token’ın TokenVersion claim’i kullanıcının güncel versiyonuyla eşleşmezse (örn. rol değişti) istek reddedilir. Bu, RBAC değişikliğinin anında etki etmesini sağlar.

Ortama göre değişen davranış

DavranışDevelopmentStagingProduction
CORS policyAllowAllAllowedBackofficePolicyAllowedBackofficePolicy
Swagger UI + ScalarAçıkAçıkKapalı
ScalarAçıkAçıkRequireAuthorization()
ASPNETCORE_ENVIRONMENTDevelopmentStagingProduction

Sonraki adımlar

Controller deseni

İnce controller’lar, base class’lar, ProblemDetails hata yanıtları.

OpenAPI / Swagger

NSwag, üç security scheme, Scalar, client üretimi.

Frontend SPA'lar

React 19 + Vite, axios interceptor, Keycloak entegrasyonu.

Gözlemlenebilirlik

Serilog → Seq, Prometheus /metrics, health endpoint’leri.