Theo nguyên lý thiết kế micro-frontends, các thành phần được triển khai phân tán và độc lập với nhau, vì thế trong trường hợp lý tưởng thì không nhất thiết cần có sự giao tiếp giữa các module. Trong thực tế, khi người dùng tương tác với các thành phần trên trang web, chương trình cần phải thông báo để kích hoạt các micro-frontends, và đặc biệt khi một trang web chứa nhiều micro-frontends thì việc thực hiện tác vụ này không phải là một điều dễ dàng. Bên cạnh đó, việc quản lý để đảm bảo sự nhất quán và gắn kết giữa các thành phần giao diện cho phía người dùng là một vấn đề cần quan tâm.
Để giải quyết yêu cầu trên, người ta sử dụng mô hình quản lý sự kiện “Pub/Sub”19
và áp dụng mẫu thiết kế “Observer/Subcriber”20. Để thực hiện, chúng ta sử dụng một trục tích hợp các sự kiện, gọi là “EventBus”21. Eventbus cho phép các thành phần tách biệt nhau có thể giao tiếp với nhau thông qua các sự kiện bằng cách gửi các sự kiện qua một trục (gọi là bus) trong một micro-frontend và gửi thông báo sự kiện tới từng micro- frontend khác. Khi một thành phần nào đó quan tâm tới sự kiện này, nó sẽ lắng nghe và phản hồi lại [27].
Hình 2.16 mô tả cơ chế giao tiếp giữa ba thành phần giao diện riêng biệt trên cùng một trang bằng cách sử dụng EventEmitter22, một đối tượng của Angular cung cấp cơ chế quản lý sự kiện theo mô hình của một eventbus. Một điểm cần nhấn mạnh ở đây là để sử dụng eventbus, thành phần container phải khởi tạo eventbus và chèn nó vào bên trong các micro-frontends của trang web.
18 https://angular.io/api/router/RouterModule
19 https://docs.microsoft.com/en-us/azure/architecture/patterns/publisher-subscriber 20 https://refactoring.guru/design-patterns/observer
21 http://www.rribbit.org/eventbus.html 22 https://angular.io/api/core/EventEmitter
39
Trong quá trình quản lý sự kiện, nhiều khi lập trình viên cần phải tùy biến để tạo ra các sự kiện theo ý của mình, những sự kiện theo kiểu này được gọi là “custom events”. Để cài đặt giải pháp này, các sự kiện cần phải được gắn vào một đối tượng dùng chung cho tất cả các micro-frontends giống như cách sử dụng một thành phần gọi là “Window Object”23 trong trình duyệt.
Đoạn mã nguồn trong hình 2.17 mô tả việc tạo một “custom event” sử dụng Emitter trong Angular.
Hình 2.16. Giao tiếp giữa các micro-frontends sử dụng EventEmitter
40
Hình 2.17. Tạo một custom event trong Angular
Tóm lược chương 2
Kết thúc chương 2, luận văn đã tập trung làm rõ một số phạm trù cốt lõi sau của kiến trúc micro-frontends:
• Giới thiệu sơ lược về một số mô hình phát triển web như mô hình web tĩnh, mô hình web động và mô hình ứng dụng SPA.
• Giới thiệu tổng quan về kiến trúc micro-frontends và một số đặc trưng cũng như lợi ích mà nó mang lại. Micro-frontends thực chất có thể coi là microservices cho phía giao diện, cho nên nó mang đầy đủ các đặc điểm, nguyên tắc thiết kế của microservices.
• Giải thích cơ chế tích hợp các micro-frontends theo hai hướng là “tích hợp tại thời điểm xây dựng” và “tích hợp tại thời điểm thực thi”. Hai kỹ thuật chính để tích hợp theo hướng thực thi là “hợp thành phía máy khách” (có thể sử dụng iframe, JavaScript hay các thành phần web) và “hợp thành phía máy chủ”.
• Việc điều hướng giữa các micro-frontends có thể được thực hiện ở phía máy khách (sử dụng app shell) hoặc điều hướng phía máy chủ (sử dụng routing server hay frontend proxy).
• Các micro-frontends giao tiếp với nhau thông qua một trục tích hợp các sự kiện, gọi là EventBus. Cơ chế tương tác này được thực hiện bằng cách áp dụng mô hình quản lý sự kiện “Pub/Sub” và áp dụng mẫu thiết kế “Observer/Subcriber”.
41
CHƯƠNG 3.XÂY DỰNG ỨNG DỤNG THỬ NGHIỆM THEO HƯỚNG
MICROSERVICES VÀ MICRO-FRONTENDS
Chương 3 tập trung trình bày cách thức xây dựng một ứng dụng thử nghiệm dựa trên kiến trúc microservices và micro-frontends. Các bước trong quá trình phát triển hệ thống từ khâu phân tích, thiết kế đến cài đặt và kiểm thử sẽ được giải thích chi tiết.