C# / .NET // .NETD::03 ORTA
20m READCOMPLETION: 87%ID::CS-101

ASP.NET CORE REST API TASARIMI

Controller-based API, middleware pipeline ve authentication

ASP.NET Core, Microsoft'un açık kaynaklı, cross-platform web framework'üdür. RESTful API geliştirmek için endüstri standardı olan Controller-based yaklaşımı ve modern middleware pipeline'ı ile kurumsal seviye uygulamalar oluşturabilirsiniz.

Proje Oluşturma

Controller Temelleri

// CSHARP //
using Microsoft.AspNetCore.Mvc;
 
namespace MyApi.Controllers;
 
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IProductRepository _repo;
    private readonly ILogger<ProductsController> _logger;
 
    public ProductsController(IProductRepository repo, ILogger<ProductsController> logger)
    {
        _repo = repo;
        _logger = logger;
    }
 
    [HttpGet]
    public async Task<ActionResult<IEnumerable<ProductDto>>> GetAll(
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 20)
    {
        var products = await _repo.GetPagedAsync(page, pageSize);
        return Ok(products);
    }
 
    [HttpGet("{id:int}")]
    public async Task<ActionResult<ProductDto>> GetById(int id)
    {
        var product = await _repo.FindByIdAsync(id);
        if (product is null)
            return NotFound(new { Message = $"Ürün #{id} bulunamadı." });
 
        return Ok(product);
    }
 
    [HttpPost]
    public async Task<ActionResult<ProductDto>> Create([FromBody] CreateProductRequest request)
    {
        var product = await _repo.CreateAsync(request);
        return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
    }
}

Dependency Injection

ASP.NET Core, DI'yi birinci sınıf vatandaş olarak destekler. Program.cs içinde servislerinizi kaydedin:

// CSHARP //
// Program.cs
var builder = WebApplication.CreateBuilder(args);
 
// Servis kaydı
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
 
// Repository kaydı (Scoped = istek başına yeni instance)
builder.Services.AddScoped<IProductRepository, ProductRepository>();
builder.Services.AddScoped<IEmailService, SmtpEmailService>();
 
// DbContext kaydı
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("Default")));
 
var app = builder.Build();

Middleware Pipeline

// CSHARP //
// Program.cs — middleware sırası önemlidir!
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
 
app.UseHttpsRedirection();
app.UseCors("AllowFrontend");
app.UseAuthentication();  // Önce authentication
app.UseAuthorization();   // Sonra authorization
app.MapControllers();
 
app.Run();

Data Transfer Objects (DTO) ve FluentValidation

// CSHARP //
// DTO — sadece gerekli alanları dışarı açar
public record ProductDto(int Id, string Name, decimal Price, bool InStock);
 
// Request DTO
public record CreateProductRequest(
    string Name,
    decimal Price,
    int CategoryId,
    string? Description
);
 
// Validator
public class CreateProductValidator : AbstractValidator<CreateProductRequest>
{
    public CreateProductValidator()
    {
        RuleFor(x => x.Name)
            .NotEmpty()
            .MaximumLength(200);
 
        RuleFor(x => x.Price)
            .GreaterThan(0)
            .LessThan(1_000_000);
 
        RuleFor(x => x.CategoryId)
            .GreaterThan(0);
    }
}

Global Exception Handling

// CSHARP //
// Middleware olarak global hata yakalama
public class GlobalExceptionMiddleware(RequestDelegate next, ILogger<GlobalExceptionMiddleware> logger)
{
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await next(context);
        }
        catch (NotFoundException ex)
        {
            logger.LogWarning(ex, "Resource not found");
            context.Response.StatusCode = 404;
            await context.Response.WriteAsJsonAsync(new { Error = ex.Message });
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Unhandled exception");
            context.Response.StatusCode = 500;
            await context.Response.WriteAsJsonAsync(new { Error = "Sunucu hatası oluştu." });
        }
    }
}
 
// Program.cs
app.UseMiddleware<GlobalExceptionMiddleware>();

Endpoint Güvenliği

// CSHARP //
// Controller seviyesinde
[ApiController]
[Route("api/[controller]")]
[Authorize]  // Tüm endpoint'ler için authentication gerekli
public class OrdersController : ControllerBase
{
    [HttpGet]
    public IActionResult GetMyOrders()
    {
        var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
        // ...
    }
 
    [HttpDelete("{id}")]
    [Authorize(Roles = "Admin")]  // Sadece Admin rolü
    public async Task<IActionResult> Delete(int id) { /* ... */ }
 
    [AllowAnonymous]  // Auth bypass
    [HttpGet("public")]
    public IActionResult PublicEndpoint() => Ok("Herkese açık.");
}

Sonuç

ASP.NET Core Controller-based API, kurumsal seviye uygulamalar için güçlü bir temel sunar. Middleware pipeline, DI sistemi ve attribute-based routing ile bakımı kolay, güvenli ve performanslı API'ler inşa edebilirsiniz. Bir sonraki derste Entity Framework Core ve migration yönetimini ele alacağız.