Chào anh em, anh em đã bao giờ đối mặt với việc mapping data giữa các services chưa. Nếu rồi ắt hẳn anh em cũng gặp nhiều vất vả! Ví dụ service A anh em lưu userId trong 1 bảng X nào đó, nhưng data của user lại nằm trong service B. Response cần trả ra cho phía client(FE) cần có 1 vài thông tin của user như tên, email hay số điện thoại, thậm chí là 1 bảng nào đó link với bảng user của service B như là additionalData chẳng hạn. Việc mapping dữ liệu có vẻ sẽ tốn công. Khi đối mặt với 1 vài trường có thể anh em còn đỡ chán nhưng khi số lượng trường trở nên quá nhiều hay có nhiều nested object... thì việc mapping lại trở nên ác mộng. Em xin giới thiệu với anh em 1 open source(OS): https://github.com/quyvu01/Anemoi_Open, cái này có cả bài hướng dẫn trên medium nhưng việc attach link có thể dẫn tới spam nên em xin phép được attach sau ạ. Về cơ bản, OS này dựa trên Attribute-based(Annotation-based) để thực hiện ý đồ, phía dưới sử dụng mediator pattern + request/reply pattern để triển khai việc data transform và mapping data.
public sealed class OrganizationResponse : ModelResponse
{ ... public string Name { get; set; } public string TaxCode { get; set; } public string ProvinceId { get; set; } [ProvinceOf(nameof(ProvinceId))] public string ProvinceName { get; set; } public string DistrictId { get; set; } [DistrictOf(nameof(DistrictId))] public string DistrictName { get; set; } ...
}
như ví dụ trên đây, việc lấy dữ liệu ProviceName và DistrictName hết sức đơn giản, chỉ cần thêm Attribute [ProvinceOf] hoặc [DistrictOf]. Ngoài ra nếu anh em ko có dữ liệu của ProvinceId thì hoàn toàn có thể sử dụng [DistrictOf(nameof(DistrictId), Expression = "Province.Name")]
public sealed class OrganizationResponse : ModelResponse
{ ... public string Name { get; set; } public string TaxCode { get; set; } public string ProvinceId { get; set; } [DistrictOf(nameof(DistrictId), Expression = "Province.Name")] public string ProvinceName { get; set; } public string DistrictId { get; set; } [DistrictOf(nameof(DistrictId))] public string DistrictName { get; set; } ...
}
Trong đó Province và District được lưu ở MasterData như ví dụ sau
public sealed class Province : ValueObject
{ public ProvinceId Id { get; set; } public string Name { get; set; } ... public List<District> Districts { get; set; } protected override IEnumerable<object> GetEqualityComponents() { yield return Name; }
} public sealed class District : ValueObject
{ public DistrictId Id { get; set; } public ProvinceId ProvinceId { get; set; } public Province Province { get; set; } public string Name { get; set; } ... protected override IEnumerable<object> GetEqualityComponents() { yield return Name; }
}
Trên đây e giới thiệu qua cách sử dụng của OS này, chapper tới e sẽ giải thích cách thức hoạt động của nó nhé!