VieTopik
Tiếng HànTiếng AnhIT
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
ASP.NET Core Web APICấu trúc ứng dụng
Bài 12/19
5 phút

Middleware và pipeline

Nội dung bài · 5 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt

Để đo mỗi request mất bao lâu, bạn không muốn thêm code đo vào từng action. Việc chung cho mọi request như vậy nên làm ở một chỗ, trước khi request tới controller. Chỗ đó là pipeline.

Khái niệm

🚰 Pipeline: chuỗi các bước mà mọi request đi qua trước khi tới controller, rồi response đi ngược lại qua đúng các bước đó.

🧱 Middleware: một bước trong pipeline, xử lý request, gọi bước tiếp theo, rồi xử lý response.

Request Middleware A Middleware B Controller Middleware B xử lý response Middleware A xử lý response Response
Request đi xuôi qua từng middleware, response đi ngược lại

Ví dụ

using System.Diagnostics;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();

var app = builder.Build();

app.Use(async (context, next) =>
{
    var watch = Stopwatch.StartNew();
    await next();
    Console.WriteLine(
        $"{context.Request.Path} " +
        $"{context.Response.StatusCode} " +
        $"{watch.ElapsedMilliseconds}ms");
});

app.MapControllers();
app.Run();
  • app.Use(...) thêm một middleware vào pipeline. Tham số là lambda nhận hai tham số (context, next), thân nhiều câu lệnh đặt trong { }.
  • Lambda cũng đánh dấu async được như method.
  • context chứa request và response hiện tại.
  • Code trước await next() chạy khi request đi vào. Code sau nó chạy khi response đi ra.
  • Stopwatch đo thời gian, cần using System.Diagnostics.
  • Middleware chạy theo đúng thứ tự được thêm trong Program.cs.

Thử ngay

Thay phần middleware ở ví dụ bằng hai middleware:

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

app.Use(async (context, next) =>
{
    Console.WriteLine("A vào");
    await next();
    Console.WriteLine("A ra");
});

app.Use(async (context, next) =>
{
    Console.WriteLine("B vào");
    await next();
    Console.WriteLine("B ra");
});

app.MapControllers();
app.Run();

Chạy server, gọi curl -i http://localhost:5000/api/products rồi xem cửa sổ đang chạy server.

Đoán trước khi chạy: bốn dòng in ra theo thứ tự nào?

Xem kết quả
A vào
B vào
B ra
A ra

Request đi xuôi A rồi B, tới controller, rồi response đi ngược B rồi A. Middleware thêm trước thì bọc ngoài middleware thêm sau.

Lỗi hay gặp

Quên await next(). Request dừng ở middleware này, controller không bao giờ chạy. Client nhận response rỗng.

// SAI — không gọi next, request không đi tiếp
var app = WebApplication.Create(args);
app.Use(async (context, next) =>
{
    Console.WriteLine("Có request");
});
// ĐÚNG
var app = WebApplication.Create(args);
app.Use(async (context, next) =>
{
    Console.WriteLine("Có request");
    await next();
});

Sửa response sau khi đã gửi. Sau await next(), response thường đã bắt đầu gửi về client. Đổi header lúc đó sẽ báo lỗi.

// SAI — header đã gửi đi, không đổi được nữa
var app = WebApplication.Create(args);
app.Use(async (context, next) =>
{
    await next();
    context.Response.Headers["X-Shop"] = "An";
});

Muốn thêm header thì đặt code đó trước await next().

// ĐÚNG — đổi header khi response chưa gửi
var app = WebApplication.Create(args);
app.Use(async (context, next) =>
{
    context.Response.Headers["X-Shop"] = "An";
    await next();
});

Tóm tắt

  • Pipeline là chuỗi middleware mà mọi request đi qua.
  • Middleware xử lý request trước await next(), xử lý response sau đó.
  • Thứ tự thêm middleware trong Program.cs là thứ tự chạy.
  • Việc chung cho mọi request như đo thời gian, ghi log nên làm ở middleware.

Tự kiểm tra

0/3 câu
Câu 1

Ba middleware X, Y, Z được thêm theo thứ tự đó. Response đi ra qua chúng theo thứ tự nào?

Câu 2

Việc nào hợp để làm bằng middleware?

Câu 3

Một middleware không gọi await next(). Chuyện gì xảy ra với request?

LoggingEF Core và DbContext

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt