Interview: Full Stack Architecture (English Version)

Frontend architecture gets a lot of attention in our discussions and writing, but the story of architecture obviously extends well beyond service communication. That's why this interview with our fullstack expert Daniel Murrmann also covers the backend perspective.

Manfred: Micro frontends aim to bring the advantages of micro services to the client side. What is your take on the connection between these two architectural styles?

Daniel: From my perspective, they are entirely separate. You can have several independent frontends for each micro service infrastructure. Looking at it this way, there doesn't have to be any link between them. Sometimes parallels do exist, but there are also situations where it makes sense to apply a completely different split in the frontend with micro frontends than you would in the micro services world.

Manfred: When talking about how micro frontends and micro services work together, people often bring up the concept of a backend for frontend, often shortened to BFF. What exactly is this, and when should you reach for it?

Daniel: In my view, a backend for frontend acts like a butler for a particular (micro)frontend. It understands what the frontend requires and serves as the ideal backend-side counterpart to it. The range of tasks a BFF can handle for a frontend is quite broad.

A key capability in micro service architectures is combining data from multiple micro services so that a frontend doesn't have to gather information from many different services on its own. This job is typically simpler and more efficiently done using the tools we have on the backend side.

Additional features that can be placed into a BFF, which I also like to refer to as an API gateway, include: authentication, authorization, routing to micro services, collecting telemetry data, and generating hypermedia documents for true RESTful APIs.

One important point to stress is that when building a single page application, achieving the best possible outcome really depends on having a BFF in place.

Manfred: You raised the topic of authentication. What approaches are available for authenticating against a Web API?

Daniel: The de facto standard these days is token-based authentication, built on the OAuth 2 and OpenId Connect specifications. A common pattern is still for a client to obtain a token from an authorization server and then use that token to authenticate at the BFF. However, the recent trend is shifting toward giving the client only an http-only cookie and keeping the token entirely on the server side to maximize security.

This adds another responsibility for the BFF: it must request the token itself, cache it, and then hand a cookie to the client.

Manfred: Okay, so that covers authentication. Where and how does authorization come into play?

Daniel: Authorization is handled quite differently across systems, since it depends heavily on what the overall system requires. In straightforward cases, it may be sufficient for a BFF to verify that certain claims exist in the token, for example, whether it permits write access or only read access. In more complex scenarios, authorization needs to determine whether a particular operation can be performed on a specific record, based on the user and business rules, all the way down to individual records. In those situations, the authorization logic is usually woven deeply into the business logic.

Manfred: Domain Driven Design is frequently mentioned alongside Micro Services. How do the two relate?

Daniel: Domain Driven Design is an excellent methodology for breaking down today's complex systems into smaller sub-problems. DDD gives us methods and tools to work systematically and objectively, moving from the (rough) requirements of a system to its actual decomposition.

What emerges at the end are what are known as bounded contexts -- these are separate solution areas, each dealing with one of the sub-problems. What's particularly appealing is that in the end, you can usually simply say that each bounded context gets implemented as its own micro service. So DDD, which originated roughly two decades ago, fits wonderfully with today's architectural approaches.

DDD isn't just useful for cutting up an entire system; it also helps in designing clean WebAPI endpoints that consistently operate on what DDD calls aggregates.

Manfred: How do you go about finding a good domain split?

Daniel: This is actually a very demanding step when designing a new architecture or system. Most importantly, it's not something you do on a regular basis. So there's very little practice involved in this activity. In my opinion, it's always wise to bring in architects who have hands-on experience with this kind of work to guide you through the process.

Since I'm trained as an agile coach myself, I tend to blend many techniques from agile development practices with DDD. I typically kick things off by defining epics and personas to set the direction. After that comes an event storming workshop. During the event storm, I attempt to spot the first possible splits based on objective criteria such as how data and functions are coupled or which events are pivotal.

Next, I turn to the DDD toolkit. I sketch out an initial context map and then test it theoretically against our event storm. If something doesn't line up, we adjust either the event storm or the context map. This loop can run several times. We know we've succeeded when the context map feels right to everyone. What we end up with on that map are the required bounded contexts and how they depend on one another.

Manfred: That sounds really interesting. The bounded contexts often end up as their own micro services. How do they talk to each other?

Daniel: There's a wide array of technologies available here. The most notable ones are probably: HTTP for synchronous communication, message and event bus systems like RabbitMQ for asynchronous communication, and when performance demands are high or you need to transfer larger binary payloads, gRPC is a solid choice.

Dive deeper: Server week 🔥

You can learn more about topics like ✅ Micro Services, ✅ REST APIs ✅ DDD and ✅ modern authentication during our server week, where we "tell the rest" of our frontend architecture story on the backend:

Daniel Murrmann has spent years working in software engineering, as well as in architecting and implementing complex distributed software systems in the industrial sector. The trained computer scientist and certified software architect uses Angular on the frontend. Daniel has also gained experience at several well-known companies and was responsible for a major Industry 4.0 project at a German machine manufacturer, which also utilized Angular for its frontend.

Daniel Murrmann