Memahami middleware

Selesai

Tujuan aplikasi web adalah untuk menerima dan menanggapi permintaan HTTP. Permintaan diterima, lalu server menghasilkan respons yang sesuai. Segala sesuatu di ASP.NET Core berkaitan dengan siklus permintaan/respons ini.

Saat aplikasi ASP.NET Core menerima permintaan HTTP, aplikasi tersebut melewati serangkaian komponen untuk menghasilkan respons. Komponen-komponen ini disebut middleware. Middleware dapat dianggap sebagai alur yang dilalui permintaan, dan setiap lapisan middleware dapat menjalankan kode sebelum dan sesudah lapisan berikutnya dalam alur.

Diagram yang menggambarkan permintaan HTTP karena beberapa middleware.

Middleware dan delegasi

Middleware diimplementasikan sebagai delegasi yang mengambil HttpContext objek dan mengembalikan Task. Objek HttpContext mewakili permintaan dan respons saat ini. Delegasi adalah fungsi yang memproses permintaan dan respons.

Sebagai contoh, perhatikan kode berikut:

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

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello world!");
});

app.Run();

Dalam kode sebelumnya:

  • WebApplication.CreateBuilder(args) membuat objek baru WebApplicationBuilder .
  • builder.Build() membuat objek baru WebApplication .
  • Yang pertama app.Run() mendefinisikan delegasi yang mengambil HttpContext objek dan mengembalikan Task. Delegasi menulis "Halo dunia!" untuk respons.
  • Yang kedua app.Run() memulai aplikasi.

Saat aplikasi menerima permintaan HTTP, delegasi dipanggil. Delegasi menulis "Halo dunia!" untuk respons dan menyelesaikan permintaan.

Middleware rantai

Di sebagian besar aplikasi, Anda memiliki beberapa komponen middleware yang berjalan secara berurutan. Urutan anda menambahkan komponen middleware ke alur adalah penting. Komponen berjalan dalam urutan ditambahkan.

Terminal dan middleware nonterminal

Setiap middleware dapat dianggap sebagai terminal atau nonterminal. Middleware nonterminal memproses permintaan dan kemudian memanggil middleware berikutnya dalam alur. Middleware terminal adalah middleware terakhir dalam alur dan tidak memiliki middleware berikutnya untuk dipanggil.

Delegasi yang ditambahkan app.Use() dapat berupa middleware terminal atau nonterminal. Delegasi ini mengharapkan HttpContext objek dan RequestDelegate objek sebagai parameter. Biasanya delegasi mencakup await next.Invoke();. Ini meneruskan kontrol ke middleware berikutnya pada alur. Kode sebelum baris tersebut berjalan sebelum middleware berikutnya, dan kode setelah baris tersebut berjalan setelah middleware berikutnya. Delegasi yang ditambahkan dengan app.Use() mendapatkan dua peluang untuk bertindak berdasarkan permintaan sebelum respons dikirim ke klien; sekali sebelum respons dihasilkan oleh middleware terminal, dan sekali lagi setelah respons dihasilkan oleh middleware terminal.

Delegasi yang ditambahkan selalu app.Run() middleware terminal. Mereka tidak memanggil middleware berikutnya dalam alur. Ini adalah komponen middleware terakhir yang berjalan. Mereka hanya mengharapkan HttpContext objek sebagai parameter. app.Run() adalah pintasan untuk menambahkan middleware terminal.

Pertimbangkan contoh berikut:

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

app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello from middleware 1. Passing to the next middleware!\r\n");

    // Call the next middleware in the pipeline
    await next.Invoke();

    await context.Response.WriteAsync("Hello from middleware 1 again!\r\n");
});

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from middleware 2!\r\n");
});

app.Run();

Dalam kode sebelumnya:

  • app.Use() mendefinisikan komponen middleware yang:
    • Menulis "Halo dari middleware 1. Meneruskan ke middleware berikutnya!" ke respons.
    • Meneruskan permintaan ke komponen middleware berikutnya dalam alur dan menunggunya selesai dengan await next.Invoke().
    • Setelah komponen berikutnya dalam alur selesai, komponen tersebut menulis "Halo dari middleware 1 lagi!"
  • Yang pertama app.Run() mendefinisikan komponen middleware yang menulis "Halo dari middleware 2!" ke respons.
  • Yang kedua app.Run() memulai aplikasi.

Pada runtime, ketika browser web mengirim permintaan ke aplikasi ini, komponen middleware berjalan dalam urutan ditambahkan ke alur. Aplikasi mengembalikan respons berikut:

Hello from middleware 1. Passing to the next middleware!
Hello from middleware 2!
Hello from middleware 1 again!

Middleware bawaan

ASP.NET Core menyediakan sekumpulan komponen middleware bawaan yang dapat Anda gunakan untuk menambahkan fungsionalitas umum ke aplikasi Anda. Selain komponen middleware yang ditambahkan secara eksplisit, beberapa middleware secara implisit ditambahkan untuk Anda secara default. Misalnya, WebApplication.CreateBuilder() mengembalikan WebApplicationBuilder yang menambahkan middleware perutean halaman pengecualian pengembang, menambahkan middleware autentikasi dan otorisasi secara kondisional jika layanan terkait dikonfigurasi, dan menambahkan middleware perutean titik akhir.

Misalnya, pertimbangkan file Program.cs berikut:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseAntiforgery();

app.MapStaticAssets();
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();

Dalam kode sebelumnya:

  • app.UseExceptionHandler() menambahkan komponen middleware yang menangkap pengecualian dan mengembalikan halaman kesalahan.
  • app.UseHsts() menambahkan komponen middleware yang mengatur header Strict-Transport-Security.
  • app.UseHttpsRedirection() menambahkan komponen middleware yang mengalihkan permintaan HTTP ke HTTPS.
  • app.UseAntiforgery() menambahkan komponen middleware yang mencegah serangan pemalsuan permintaan lintas situs (CSRF).
  • app.MapStaticAssets() dan app.MapRazorComponents<App>() memetakan rute ke titik akhir, yang kemudian ditangani oleh middleware perutean titik akhir. Middleware perutean titik akhir secara implisit ditambahkan oleh WebApplicationBuilder.

Ada lebih banyak komponen middleware bawaan yang dapat Anda gunakan di aplikasi tergantung pada jenis aplikasi dan kebutuhan Anda. Periksa dokumentasi untuk daftar lengkapnya.

Petunjuk / Saran

Dalam konteks ini, metode yang dimulai dengan Use umumnya untuk memetakan middleware. Metode yang dimulai dengan Map umumnya untuk memetakan titik akhir.

Penting

Komponen middleware pesanan ditambahkan ke masalah alur! Komponen middleware tertentu harus berjalan sebelum yang lain bekerja dengan benar. Periksa dokumentasi untuk setiap komponen middleware untuk menentukan urutan yang benar.