Header Propagation trong AspNet Core
December 24, 2020Đặt vấn đề:
Bạn có từng chú ý đến các header trong một request từ network của một trang web bất kỳ lần nào chưa. Khi phía client giao tiếp với phía server thông qua request, thì bạn có rất nhiều cách truyền nhận dữ liệu giữa 2 bên. Và một trong số cách truyền nhận client-server này chính là giao thức http (hyper text transfer protocol). Một giao thức sẽ có cấu trúc chính gồm method, header và body.
Điều mình chú ý trong bài viết này chính là Header. Bạn thử nhìn vào một request từ spiderum, nó sẽ chứa rất nhiều thông tin phụ dùng chung cho các request như Content-Type, Cookie hay Token. Những thông tin này được định nghĩa và sử dụng chung mà một request bất kỳ được gọi tới đều có thể sử dụng chúng.
Tuy nhiên, có một số trường hợp bạn muốn customs keys và values trong header với mục đích sử dụng trong logic nghiệp vụ của bạn. Ví dụ mình có một số nghiệp vụ như multi-language bạn cần phải trao đổi thông tin phía client là ở nước nào để có thể chuyển đổi ngôn ngữ của website sao cho phù hợp. Hay trường hợp bạn phân quyền theo role mà tài khoản bạn đăng nhập, bạn sẽ phải định nghĩa những permission và thông qua authorization bạn có thể phân biệt được user đó thuộc role nào và chỉ hiển thị trang phù hợp với role đó.
Nhưng chuyện không chỉ dừng lại ở đó. Đối với microservice thì những thông tin header đó sẽ phát sinh động và được truyền và thêm bớt khi nó đi qua mỗi service khác nhau. Khi đó bạn phải quản lý phần customs header này sao cho hợp lý là một vấn đề đáng lưu tâm.
Ý tưởng:
Bạn sẽ định nghĩa key và value mặc định cho một header mà bạn muốn customs. Sau khi đi qua các service khác nhau trong microservice hay đi từ front end xuống, bạn chỉ việc thêm và cập nhật giá trị của header đó vào phần đuôi của header chính. Mục đích gắn thêm này nhằm để đảm bảo những header cũ vẫn tồn tại và được sử dụng ở những request khác và tránh việc thiếu header khi thực hiện lần request trong quá khứ và tương lai.
Vấn đề được mở rộng hơn khi bạn gọi một service từ bên thứ 3, bạn lại không có quyền sửa đổi các giá trị đầu vào trong header của họ, khi đó bạn cũng thực hiện bằng cách kế thừa và gắn thêm phần header customs của bạn ở phía sau nhằm đảm bảo các request của bên thứ 3 không bị ảnh hưởng mà bạn vẫn sử dụng tốt đối với mục đích hiện tại của bạn.
Giải quyết vấn đề:
Trong các ngôn ngữ nói chung và ngôn ngữ DotNet nói riêng, có một thuật ngữ nhằm xử lý vấn đề này. Đó là Header Propagation.
Dưới đây là 2 hình vẽ nói lên ý tưởng xử lý này:
Với hình vẽ đầu tiên, bạn nhận header từ App sau đó chuyển qua service 1 bạn sửa hoặc thêm header sao cho phù hợp để xử lý nghiệp vụ của service 1, sau đó chuyển qua service 2 bạn cũng sửa và cập nhật header đối với service 2.
Bạn thấy mình đã thử gọi một hàm update header khi chạy vào service thứ 2.
Đối với trường hợp bạn nhận header từ External API từ bên ngoài cũng vậy, bạn cũng có thể làm với cơ chết tương tự.
Mình sẽ để code demo dưới bài viết. Mình chỉ có 2 lưu ý nhỏ khi bạn thực hiện header propagation thôi.
Thứ nhất là đừng quên khai báo sử dụng trong startup.cs
// Add header propagation middleware
app.UseHeaderPropagation();
Thứ 2 là đừng quên định nghĩa cho header mà bạn muốn customs nhé
// Define all headers you would like to propogate
services.AddHeaderPropagation(options
=> options.Headers.Add("Ntech-Header"));
// Define DelegatingHandler which handles before sending request to external Api
services.AddHttpClient("externalapi-client", options
=> options.BaseAddress = new Uri("https://localhost:5001"))
.AddHeaderPropagation();
Ok, bạn có thể tham khảo code tại đây nhé!
# Github
[…] Inversion Principle – DRY, KISS, YAGNI [Asp Net Core Basic] – Web Api + https://blog.ntechdevelopers.com/header-propagation-trong-aspnet-core/ – Rest – Routing – Middlewares – Filter and Attributes – Application […]