Docs .NET Development ASP.NET Core Dasar

ASP.NET Core Dasar

Pengenalan ASP.NET Core untuk membangun web API dan aplikasi web

ASP.NET Core Dasar

ASP.NET Core adalah framework web modern dari Microsoft untuk membangun web applications, APIs, dan microservices. Framework ini cross-platform, high-performance, dan sangat populer di kalangan enterprise.

Apa itu ASP.NET Core?

ASP.NET Core adalah:

  • Cross-platform — Berjalan di Windows, Linux, dan macOS
  • High-performance — Salah satu web framework tercepat
  • Open-source — Dikembangkan secara terbuka di GitHub
  • Modular — Hanya include apa yang dibutuhkan

Membuat Project API Pertama

1. Buat Project

# Buat project Web API
dotnet new webapi -n MyFirstApi
cd MyFirstApi

# Jalankan
dotnet run

Buka browser ke http://localhost:5000/swagger untuk melihat Swagger UI.

2. Struktur Project

MyFirstApi/
├── Controllers/
│   └── WeatherForecastController.cs
├── Properties/
│   └── launchSettings.json
├── appsettings.json
├── appsettings.Development.json
├── Program.cs
└── MyFirstApi.csproj

3. File Program.cs

Di .NET 8, file Program.cs sangat minimal:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

Controllers dan Endpoints

Basic Controller

using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    // GET api/products
    [HttpGet]
    public IActionResult GetAll()
    {
        var products = new[]
        {
            new { Id = 1, Name = "Laptop", Price = 15000000 },
            new { Id = 2, Name = "Mouse", Price = 250000 },
        };
        return Ok(products);
    }
    
    // GET api/products/1
    [HttpGet("{id}")]
    public IActionResult GetById(int id)
    {
        var product = new { Id = id, Name = "Laptop", Price = 15000000 };
        return Ok(product);
    }
    
    // POST api/products
    [HttpPost]
    public IActionResult Create([FromBody] ProductDto product)
    {
        // Simpan ke database
        return CreatedAtAction(nameof(GetById), new { id = 1 }, product);
    }
    
    // PUT api/products/1
    [HttpPut("{id}")]
    public IActionResult Update(int id, [FromBody] ProductDto product)
    {
        // Update di database
        return NoContent();
    }
    
    // DELETE api/products/1
    [HttpDelete("{id}")]
    public IActionResult Delete(int id)
    {
        // Hapus dari database
        return NoContent();
    }
}

public record ProductDto(string Name, decimal Price);

HTTP Response Codes

return Ok(data);           // 200
return Created(uri, data); // 201
return NoContent();        // 204
return BadRequest();       // 400
return Unauthorized();     // 401
return NotFound();         // 404
return Conflict();         // 409

Dependency Injection

ASP.NET Core memiliki built-in DI container:

1. Membuat Service

// Interface
public interface IProductService
{
    List<Product> GetAll();
    Product? GetById(int id);
    void Add(Product product);
}

// Implementation
public class ProductService : IProductService
{
    private readonly List<Product> _products = new();
    
    public List<Product> GetAll() => _products;
    
    public Product? GetById(int id) => _products.FirstOrDefault(p => p.Id == id);
    
    public void Add(Product product) => _products.Add(product);
}

2. Register di Program.cs

var builder = WebApplication.CreateBuilder(args);

// Register services
builder.Services.AddScoped<IProductService, ProductService>();

// ... rest of configuration

3. Gunakan di Controller

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IProductService _productService;
    
    // Constructor injection
    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }
    
    [HttpGet]
    public IActionResult GetAll()
    {
        var products = _productService.GetAll();
        return Ok(products);
    }
}

Service Lifetimes

// Transient - dibuat setiap kali direquest
builder.Services.AddTransient<IMyService, MyService>();

// Scoped - 1 instance per HTTP request
builder.Services.AddScoped<IMyService, MyService>();

// Singleton - 1 instance untuk seluruh aplikasi
builder.Services.AddSingleton<IMyService, MyService>();

Validation

Model dengan Data Annotations

using System.ComponentModel.DataAnnotations;

public class CreateProductDto
{
    [Required(ErrorMessage = "Nama produk wajib diisi")]
    [StringLength(100, MinimumLength = 3)]
    public string Name { get; set; }
    
    [Required]
    [Range(1, 1000000000, ErrorMessage = "Harga harus antara 1 dan 1 miliar")]
    public decimal Price { get; set; }
    
    [EmailAddress]
    public string? SupplierEmail { get; set; }
}

Validasi di Controller

[HttpPost]
public IActionResult Create([FromBody] CreateProductDto dto)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    
    // Process...
    return Ok();
}

Configuration

appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=MyDb;..."
  },
  "AppSettings": {
    "ApiKey": "secret-key",
    "MaxPageSize": 100
  }
}

Mengakses Configuration

// Di Program.cs
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");

// Options Pattern
public class AppSettings
{
    public string ApiKey { get; set; }
    public int MaxPageSize { get; set; }
}

builder.Services.Configure<AppSettings>(
    builder.Configuration.GetSection("AppSettings"));

// Di service/controller
public class MyService
{
    private readonly AppSettings _settings;
    
    public MyService(IOptions<AppSettings> options)
    {
        _settings = options.Value;
    }
}

Middleware

Middleware adalah komponen yang memproses HTTP request/response:

var app = builder.Build();

// Built-in middleware
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

// Custom middleware
app.Use(async (context, next) =>
{
    // Sebelum request diproses
    Console.WriteLine($"Request: {context.Request.Path}");
    
    await next();
    
    // Setelah response dibuat
    Console.WriteLine($"Response: {context.Response.StatusCode}");
});

app.MapControllers();

Minimal APIs (.NET 6+)

Alternatif yang lebih simpel dari controllers:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Simple endpoints
app.MapGet("/", () => "Hello World!");

app.MapGet("/products", () =>
{
    return new[] { new { Id = 1, Name = "Laptop" } };
});

app.MapGet("/products/{id}", (int id) =>
{
    return new { Id = id, Name = "Laptop" };
});

app.MapPost("/products", (ProductDto product) =>
{
    return Results.Created($"/products/1", product);
});

app.Run();

record ProductDto(string Name, decimal Price);

Tips Best Practices

  1. Gunakan DTOs — Jangan expose entity database langsung ke API
  2. Async/Await — Gunakan untuk operasi I/O
  3. Exception Handling — Gunakan middleware untuk global error handling
  4. Logging — Gunakan built-in ILogger
  5. Versioning — Implementasikan API versioning sejak awal

Langkah Selanjutnya

  1. Entity Framework Core — Connect ke database
  2. Authentication & Authorization — Amankan API Anda
  3. Testing — Unit dan integration testing

ASP.NET Core adalah framework yang sangat powerful. Mulai dari yang simpel, lalu tingkatkan kompleksitas sesuai kebutuhan.