Ableron UI Composition
Server Side. Dynamic. Distributed.
Your way to bring your micro frontends together using distributed server side UI composition.
Server Side - Happens in your services before sending the response to the client.
Dynamic - Composition is performed during runtime of the services instead of compile time. This makes quality assurance a bit harder, but brings significant value regarding decoupling of your teams and services.
Distributed - No centralized infrastructure component which is performing the UI composition. Instead, each service is performing UI composition itself using an Ableron library.
Find me on GitHub - github.com/ableron
How It Works
Ableron intercepts the HTTP response sent by your service and resolves all <ableron-include>
-HTML-tags
with their respective remote fragment. This is achieved via installing Ableron as a dependency in your service, which is doing the magic
Why Ableron?
Compared to Server Side Includes via nginx and thus an architecture where a dedicated infrastructure component is performing UI composition:
- Lean Infrastructure: No need to route all your traffic through the infrastructure component which is performing the UI composition
- Easy Local Development: Includes are resolved directly in your service. This works fine for local development and increases developer experience.
- Easy Configuration: Your can easily define different timeouts, fallback fragments or static fallback content for each of your includes.
- Caching: All fragments are cached in memory directly within your service according to the cache policy of the fragments. This saves HTTP calls and thus money as well as latency.
How To Use
In order to use Ableron in your service, there needs to be an Ableron library which is compatible with the technology used in your service.
Available framework integrations:
Available basic implementations:
The <ableron-include>
Tag
- Must be closed, i.e. either
<ableron-include ... />
or<ableron-include ...></ableron-include>
- Content between
<ableron-include>
and</ableron-include>
is used as fallback content - Attributes
id
: Unique name of the include used within log messagessrc
: URL of the fragment to includesrc-timeout-millis
: Timeout for requesting thesrc
URL. Defaults to globalrequestTimeout
fallback-src
: URL of the fragment to include in case the request tosrc
failedfallback-src-timeout-millis
: Timeout for requesting thefallback-src
URL. Defaults to globalrequestTimeout
primary
: Denotes a fragment whose response code is set as response code for the page
- Precedence for resolving:
src
→fallback-src
→ fallback content
Full Example:
<ableron-include
id="header"
src="https://example.com/api/fragments/header"
fallback-src="https://cdn.example.com/static/fallback-header">
<header>Static fallback header</header></ableron-include>
Primary Includes
Treating an include as primary leads to not only include the fragment but also to let the fragment control the HTTP response status code as well as response headers. How primary includes work:
- If
src
returns success status, this status code is set as response code for the page - If
src
returns error status,fallback-src
is defined and returns success status, this status code is set as response code for the page - If
src
andfallback-src
return error status, the status code returned bysrc
is set as response code for the page - If
src
andfallback-src
return error status, the fragment content equals the body returned bysrc
. Fallback content is ignored
Caching of fragments
Fragments are considered cacheable if they have HTTP status code:
200
,203
,204
,206
300
404
,405
,410
,414
501
FAQ
Q: I have added a header to cacheVaryByRequestHeaders
, but caching is not influenced. Why?
A: Most probably the header set via cacheVaryByRequestHeaders
is not sent along the fragment request.
Also add the header to fragmentAdditionalRequestHeadersToPass
or fragmentRequestHeadersToPass
to make sure it is included in the fragment request.
Q: When src
or fallback-src
of an <ableron-include>
-tag return
a redirect, will that redirect be followed?
A: No. Redirects will not be followed when requesting fragments because they may introduce unwanted latency.
Q: Does Ableron influence Cache-Control
of my pages?
A: Yes. The transclusion result provides a max-age for the content with all includes resolved, based on the fragment with the lowest expiration time. I.e., the fragment with the lowest expiration time defines the max-age of the page in case max age of the page is not below it.
Contributing
All contributions are greatly appreciated. To contribute you can either simply open an issue or fork the corresponding repository and create a pull request:
- Fork the respective repository
- Create your feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'Added some amazing feature'
- Push to your branch:
git push origin feature/amazing-feature
- Open a pull request