Till Schulte-Coerne
Dieser Artikel ist auch auf Deutsch verfügbar
System boundaries tend to be a nuisance from the user’s point of view. Thus
the motivation for the modularization of systems is purely technical and
should not hinder of frictionless workflows without
any major loss of context.
So if we have cut up our systems “for reasons”, we have to
bring them together in the frontend for our users. This can happen
at different points:
- Static overarching things like layouts can be integrated during the build or deployment.
- With dynamic content, the backend can
obtain necessary information from other systems. This can mean
making direct calls to another system to process
the request in question. In this case, a response from another system is needed
in order to answer your own request. This could also mean asynchronous interactions between servers that are decoupled from the request/response cycle, such as a feed-based replication of data. - From the author’s point of view, however, the silver bullet is integration in the frontend,
specifically in the user’s browser. This type of integration is usually
more lightweight, has better performance and has the fundamental advantage that our
own systems (i.e. the backends) do not have to wait for another system (resulting in a delay in our own response)
because the integration takes place on the user’s end device.
Much has already been said about the first two options, so this article will address the third option: frontend integration.
As so often happens in IT, there is not only one option for implemeting frontend integration, but many.
The following sections provide a list of some of the options (disclaimer: the list does not attempt to be exhaustive).
The list should begin with today’s quasi-standard. This is
the monolithic single-page app (SPA) written in the frontend framework that was trending during the year that the app was created.
Monolithic SPA
In my opinion, the ongoing microservices hype was primarily a hype in the backend.
This means that many microservice architectures arose without consideration for anything apart from the
backend. If you then find time to deal with the “little problem” of the frontend, and take the simultaneous hype for single-page apps at face value, it seems logical to integrate the backends at the level of your APIs.
A Single Page App (SPA) is then built, typically with a special team of UI/SPA experts. Normally, this app will make Ajax calls to
the REST APIs of the backend team.
What is convincing about this concept is that the web frontend is a completely
independent system. It therefore fits in seamlessly with other consumer systems
like the mobile client for iOS or the calls to a partner company, as any architect would
wish when drawing it on paper or a flipchart.
Unfortunately, a closer look reveals some technical
problems:
- Public APIs must all have cross-cutting issues such as authentication or security in general. However, this can usually be
solved somehow with infrastructure. - The naive approach to the orchestration of service calls against different backends
over the internet is the opposite of highly performant.
This is especially the case when it comes to mobile internet.
Here there are no simple technical solutions, only
architectural ones: The backend-for-frontend pattern helps out if the frontend team
is allowed to build a backend system (typically using
NodeJS). This special backend system takes over
the orchestration of the actual backends and can thus be considerably more compact
and communicate more efficiently with the frontend.
However, the main problem with this approach is not technical
but rather one of organization: by having invented a cross-sectional frontend team,
the fundamental idea of microservices is actually being violated.
Ideally, microservices should customize teams and systems around business areas,
which can never be the case with a cross-sectional team (otherwise it
wouldn’t be a cross-sectional team).
As a consequence, it is difficult to imagine that a new feature
could be implemented by one team alone. As a rule, each new functionality in the backend
will require a corresponding feature in the frontend, and vice versa,
in order for it to be usable at all.
Pros:
- There is a strict separation between the backends and the one frontend.
- Monolithic single-page apps are “state of the art”.
Cons:
- You inherit all the disadvantages of a monolith as well as all the disadvantages
of still having several teams. - SPA technologies are short-lived. The team becomes extremely dependent on a framework creator.
Modular SPA
However, the organizational problem of a monolithic SPA can be addressed with technical
means and some effort. To do this, the SPA is divided
into several modules that are provided by the respective specialized
teams. This means that there is still one Single Page App in exactly one
framework version. However, this app optimally loads its functionality in the form of modules
directly from the different systems and integrates them
via framework-specific interfaces.
One option for executing this approach is
[Angular lazy Feature modules] (https://angular.io/guide/lazy-loading-ngmodules).
In this case, the components of an application are distributed in various so-called Feature Modules
and are loaded only when they are needed. It is also possible to load these modules
from different sources. This mechanism can be used to
load the feature modules from different backends only
at runtime on the client.
With a proper module interface, the teams then
regain sovereignty over their functionality and are able
to develop and roll out new features independently and wholly in the spirit of
microservices.
With webpack-based projects, th