first commit
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
using Dotnet.Samples.AspNetCore.WebApi.Data;
|
||||
using Dotnet.Samples.AspNetCore.WebApi.Extensions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Serilog;
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Web Application
|
||||
* Registers all services into the DI container before the application is built.
|
||||
* Throughout this section, builder.Services refers to the ASP.NET Core
|
||||
* dependency injection (DI) container — not to be confused with the Services
|
||||
* subsection below, which registers our own application-level business logic.
|
||||
* https://learn.microsoft.com/en-us/aspnet/core/fundamentals/startup
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
/* Configurations ----------------------------------------------------------- */
|
||||
|
||||
builder
|
||||
.Configuration.SetBasePath(AppContext.BaseDirectory)
|
||||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
||||
.AddEnvironmentVariables();
|
||||
|
||||
/* Logging ------------------------------------------------------------------ */
|
||||
|
||||
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(builder.Configuration).CreateLogger();
|
||||
builder.Host.UseSerilog();
|
||||
|
||||
/* Infrastructure ----------------------------------------------------------- */
|
||||
|
||||
builder.Services.AddHealthChecks();
|
||||
builder.Services.AddCorsDefaultPolicy(builder.Environment);
|
||||
builder.Services.AddFixedWindowRateLimiter(builder.Configuration);
|
||||
|
||||
if (builder.Environment.IsDevelopment())
|
||||
{
|
||||
builder.Services.AddSwaggerConfiguration(builder.Configuration);
|
||||
}
|
||||
|
||||
/* Controllers -------------------------------------------------------------- */
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddValidators();
|
||||
|
||||
/* Services (Business Logic) ------------------------------------------------ */
|
||||
|
||||
builder.Services.RegisterPlayerService();
|
||||
builder.Services.AddMemoryCache();
|
||||
builder.Services.AddMappings();
|
||||
|
||||
/* Repositories ------------------------------------------------------------- */
|
||||
|
||||
builder.Services.RegisterPlayerRepository();
|
||||
|
||||
/* Data --------------------------------------------------------------------- */
|
||||
|
||||
builder.Services.AddPlayerDbContext(builder.Environment);
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Database Migration
|
||||
* Applies pending EF Core migrations at startup, before the app accepts requests.
|
||||
* https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/applying#apply-migrations-at-runtime
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
await using (var scope = app.Services.CreateAsyncScope())
|
||||
{
|
||||
var db = scope.ServiceProvider.GetRequiredService<PlayerDbContext>();
|
||||
await db.Database.MigrateAsync();
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Middlewares
|
||||
* Defines the order in which middleware components process each HTTP request.
|
||||
* https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware
|
||||
* https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware#middleware-order
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
// Replaces the default ASP.NET Core request logging with Serilog's structured
|
||||
// logging, emitting one log entry per request with timing, status code, and
|
||||
// other contextual properties.
|
||||
app.UseSerilogRequestLogging();
|
||||
|
||||
// Custom middleware that catches unhandled exceptions and returns a consistent
|
||||
// RFC 7807 Problem Details response instead of exposing a raw stack trace.
|
||||
app.UseExceptionHandling();
|
||||
|
||||
// Redirects all plain HTTP requests to HTTPS, enforcing transport security.
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
// DisableRateLimiting() exempts the health check endpoint from the global rate
|
||||
// limiter so that monitoring and orchestration systems can always assess
|
||||
// liveness and readiness without being throttled.
|
||||
app.MapHealthChecks("/health").DisableRateLimiting();
|
||||
|
||||
// Enforces the fixed-window rate limiting policy defined during service
|
||||
// registration, returning 429 Too Many Requests when the limit is exceeded.
|
||||
app.UseRateLimiter();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
// Only active in Development, where AddCorsDefaultPolicy registers a
|
||||
// permissive wildcard policy for Swagger UI and local frontends. No policy
|
||||
// exists in Production — the API is assumed to be consumed server-to-server
|
||||
// or behind a reverse proxy on the same origin, where CORS is not needed.
|
||||
// Must precede MapControllers so CORS headers are applied before any
|
||||
// endpoint executes, consistent with the standard middleware pipeline order.
|
||||
app.UseCors();
|
||||
|
||||
// Generates the OpenAPI JSON document consumed by Swagger UI.
|
||||
app.UseSwagger();
|
||||
|
||||
// Serves the interactive Swagger UI at /swagger, allowing manual
|
||||
// exploration and testing of the API endpoints during development.
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
// Routes incoming HTTP requests to the matching controller actions. Must come
|
||||
// after all middleware that needs to run before endpoint execution (CORS, rate
|
||||
// limiting, etc.).
|
||||
app.MapControllers();
|
||||
|
||||
await app.RunAsync();
|
||||
|
||||
public partial class Program
|
||||
{
|
||||
protected Program() { }
|
||||
}
|
||||
Reference in New Issue
Block a user