We want to make it possible to use Bahmni Forms in OpenMRS 3.0 using Microfrontends. For this we don’t want to reinvent the wheel, but rather use as much as possible from the existing implementation.
Right now Bahmni Forms is mostly delivered to the frontend using the implementer-interface
package. This package depends on bahmni-form-controls
, which is the library delivering most of the components.
The architecture thus looks roughly like:
The bahmni-form-controls
implicitly enforces a number of anti-patterns:
- It performs HTTP calls directly rather than leaving that to the consuming application (i.e., these calls cannot be configured or left to a global handler)
- It comes with global styles to be applied rather than allowing the consuming application to override or set these
- It is delivered in a pre-bundled state, which makes it inefficient for use in arbitrary applications. While some dependencies are rather small (
classnames
), others are significant (lodash
,immutable
). - It delivers some components, but misses others, which are crucial (e.g., all the drag and drop handling), effectively resulting in just barely over half of the required components.
- Puts a significant amount of logic in view-driven components instead of distinguishing between controller components and view components.
We already had a call with @binduak @angshuonline @buvaneswariarun @snehabagri thanks to the help of @mksd - there we introduced the topic and the possible options.
There are three distinct ways of introducing the implementer-interface
to microfrontends. Variations of the three ways are possible, too:
-
Fork and pick (Re-assemble
bahmni-form-controls
andimplementer-interface
components / code in a new repository) -
Use a generalized output from
implementer-interface
as actual basis; for the actualimplementer-interface
standalone application and the microfrontend version -
Build the microfrontend version from the same repository
All have their pros and cons. While (1) has the most effort, (3) has the greatest technical challenges.
We would favor a variation of (2) where all controls would be placed in bahmni-form-controls
and implementer-interface
would still just consume these controls from the library. It would thus reduce the creation of a new Bahmni Forms app to wiring together the components exported by bahmni-form-controls
.
To be really flexible the styling and some other inner workings would need some adjustments, too.
In total, the previously shown architecture diagram would change to look as follows:
When implementing this architecture the following things would require change:
-
bahmni-form-controls
should be delivered in a library state, i.e., not pre-bundled -
bahmni-form-controls
should not require global CSS to be applied and comes with isolated / changeable styling -
implementer-interface
shifts most of its components tobahmni-form-controls
, except application dependent components such as the specificRouter
-
All components in
bahmni-form-controls
are configurable with respect to their used API functions / calls, i.e., if a component depends on an API call this has to be resolved via a given prop (or alternatively via a context required bybahmni-form-controls
)
Consequently, the implementer-interface
would change slightly internally, however, remain as-is from the outside. In this setup there are multiple locations for new applications such as the microfrontend app:
-
Within the same repository (
implementer-interface
becomes a monorepo for all apps) -
Within new repositories (but using the same GitHub organization)
-
Within new repositories (organization independent)
Right now there is no recommendation for the location of these applications. For the microfrontend app specifically we would recommend to choose a location that suits the responsible/maintaining team.
As a result, the architecture for supporting the standalone application together with a new microfrontend app would look as follows:
A discussion resulting in next steps and further insights would be greatly appreciated!
Cc @angshuonline @binduak @snehabagri @buvaneswariarun @kirity @jdick @bistenes @burke