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

UI Composition Flow

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 messages
    • src: URL of the fragment to include
    • src-timeout-millis: Timeout for requesting the src URL. Defaults to global requestTimeout
    • fallback-src: URL of the fragment to include in case the request to src failed
    • fallback-src-timeout-millis: Timeout for requesting the fallback-src URL. Defaults to global requestTimeout
    • primary: Denotes a fragment whose response code is set as response code for the page
  • Precedence for resolving: srcfallback-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 and fallback-src return error status, the status code returned by src is set as response code for the page
  • If src and fallback-src return error status, the fragment content equals the body returned by src. 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:

  1. Fork the respective repository
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Added some amazing feature'
  4. Push to your branch: git push origin feature/amazing-feature
  5. Open a pull request