ProgrammingPro #82: Domain-Driven Design for Micro Frontends, .NET 9's JSON Boost, and Python Automation Scripts
Welcome to this week’s edition of ProgrammingPro!
In today’s Expert Insight, we bring you an excerpt from the recently published book, The Art of Micro Frontends - Second Edition, which explains how Domain-Driven Design principles can help define and organize boundaries for micro frontends to ensure modular, isolated, and efficient architecture.
News Highlights: .NET 9 launches with major performance boosts, including a 50% JSON processing gain; Java 24 targets memory savings with smaller object headers via Project Lilliput; the US urges developers to move from C and C++ for security; and GitHub Copilot chat adds prompt rewording guidance.
My top 5 picks from today’s learning resources:
Implementing the Repository Pattern with Multiple Databases in C# Clean Architecture🏗️
Optimize Database Performance in Ruby on Rails and ActiveRecord🚄
But there’s more, so dive right in.
Stay Awesome!
Divya Anne Selvaraj
Editor-in-Chief
P.S.: This month's survey is now live. Do take the opportunity to leave us your feedback, request a learning resource, and earn your one Packt credit for this month.

🗞️News and Analysis🔎
.NET 9 is now available with several performance improvements: The version introduces a 15% increase in requests per second, optimized Server GC, faster LINQ operations, and a 50% boost in
System.Text.Json
processing.Java 24 to Reduce Object Header Size and Save Memory: This optimization is part of Project Lilliput and aims to improve memory density, reduce garbage collection pressure, and benefit workloads with small object sizes.
Go language rises in Tiobe popularity index: The Google-developed Go language has reached its highest rank, seventh, in November 2024. Go aims to overtake JavaScript (ranked sixth) within three years.
OpenJDK News Roundup: Instance Main Methods, Flexible Constructor Bodies, Module Import Declarations: With 19 JEPs targeted so far, JDK 24 is set for release in March 2025, featuring a robust set of updates aimed at performance, security, and language flexibility.
The US government wants developers to stop using C and C++: While CISA mandates roadmaps for migration by 2026, widespread adoption is unlikely in the near future due to resistance, cost, and existing industry priorities.
GitHub Copilot chat now provides guidance on rewording prompts: The updated chat suggests more specific prompts when a query lacks context, available in Visual Studio 2022 17.12 Preview 3 and above
Cloudflare Advocates for Broader Adoption of security.txt Standard for Vulnerability Reporting: Cloudflare has introduced a dashboard to create and manage security.txt files for vulnerability reporting, aligning with the RFC9116.
🎓Tutorials and Learning Resources💡
Python
💡20 Python scripts to automate common daily tasks: Lists scripts for tasks such as sending emails, scraping news, downloading stock prices, backing up files, posting to social media, fetching weather updates, and resizing images.
For more Python resources, go to PythonPro
C# and .NET
🎓Tutorial | Pushed Authorization Requests (PAR) in ASP.NET Core 9: Explains how the new support for PAR enhances security in OAuth and OpenID Connect by moving sensitive data to secure back-channel requests.
💡You Probably Don’t Need Those Interfaces: Challenges the common practice of using interfaces for every dependency, arguing that interfaces may be unnecessary for unit testing (due to modern mocking frameworks).
🎓Tutorial | Implementing the Repository Pattern with Multiple Databases in C# Clean Architecture: Demonstrates using separate
DbContext
instances for different data types and aRepositoryFactory
.
C and C++
🗞️A new chapter, and thoughts on a pivotal year for C++: Herb Sutter, the ISO C++ committee chair, has joined Citadel Securities, where he will lead C++ training and strategy while continuing his C++ standards work.
🎓Tutorial | Around the World in C++: Exploring Time Zones with std::chrono: Explores time zone handling using C++20’s
<chrono>
library, demonstrating how to identify unusual time zones with non-hour UTC offsets.🧾The Design of a Self-Compiling C Transpiler Targeting POSIX Shell: Presents pnut, a C-to-POSIX shell transpiler designed to counteract software supply chain risks by enabling reproducible builds without relying on precompiled binaries.
Java
📖Open Access Book | Modern Java by Ethan McCue: Provides a structured introduction to Java, covering basics like data types, control flow, and methods, then progressing to complex topics such as classes and data structures.
🎓Tutorial | How to Handle Errors Cleanly in Java: Principles for Scalable, Maintainable Code: Covers using custom exceptions, avoiding generic catch-all blocks, leveraging checked exceptions, and utilizing Optional to handle nulls.
🎓Tutorial | Creating GenAI Apps in Java with SD4J (Stable Diffusion for Java) and the ONNX Runtime — Part 1: Details the setup of prerequisites such as JDK, ONNX Runtime, and Hugging Face tools, followed by step-by-step instructions to generate custom images from text prompts.
JavaScript and TypeScript
🎓Tutorial | JavaScript's ??= Operator: Default Values Made Simple: Explains the operator's functionality, benefits over previous methods, and practical use cases for retaining meaningful falsy values.
🎓Tutorial | Generating Random Mazes with JavaScript: Walks you through building a random maze generator in JavaScript using a three-step process with tips on handling blocked paths and using helper functions to manage grid cells.
🎓Tutorial | Exploring Effect in TypeScript: Simplifying Async and Error Handling: Showcases how Effect can replace multiple libraries like Zod and Lodash, improving code readability and robustness in complex applications.
Go
🎓Tutorial | Functional programming in Go: Focuses on using functions as the primary control structures, enabling operations like
map
,filter
, andreduce
to simplify and streamline data processing tasks.🎓Tutorial | ML in Go with a Python sidecar: Explores using ML in Go applications, focusing on techniques to integrate Python-based ML models, from cloud-based APIs to local sidecar servers.
Rust
💼Case Study | Why I love Rust for tokenising and parsing: Covers the author’s development experience using Rust to build
sqleibniz
, a static analysis tool for SQLite, focusing on Rust’s macro system, testing frameworks, and more.🎓Tutorial | How to rewrite a C++ codebase successfully: Provides a structured guide for incrementally rewriting a legacy C++ codebase in Rust, focusing on real-world challenges such as cross-platform compatibility.
Swift
🎓Tutorial | Migrating to Swift 6: Provides a comprehensive framework for migration, including strategies for enabling concurrency checking, resolving common compiler errors, and incrementally adopting concurrency features.
💡Problematic Swift Concurrency Patterns: Highlights common pitfalls and patterns to avoid when using Swift’s concurrency features, addressing issues like split isolation, excessive reliance on
Task.detached
, and more.
PHP
💡New error messages in PHP 8.4: Key updates include stricter handling of nullable parameters, limitations on unsetting hooked properties, and clearer messaging on invalid operations.
SQL
🎓Tutorial | 8 Steps in Writing Analytical SQL Queries: Steps covered include defining goals in plain language, inspecting and confirming basic data, incrementally adding joins without calculations, and using CTEs for summations.
Ruby
🎓Tutorial | Optimize Database Performance in Ruby on Rails and ActiveRecord: Covers best practices in ActiveRecord query optimization, indexing, reducing N+1 queries, batching, and caching techniques.
💼Case Study | How we made a Ruby method 200x faster: Details how the team at Campsite identified and resolved a specific performance issue in their codebase, providing insights into their debugging process.
Kotlin
🎓Tutorial | Modeling ViewModel State in Android: A Guide to Clean, Scalable Patterns: Critiques using plain data classes with multiple Boolean flags, as this approach can lead to conflicting states and increased boilerplate.
🌟Best Practices and Advice🚀
Efficient Resource Management with Small Language Models (SLMs) in Edge Computing: Covers model optimization, latency reduction, and memory efficiency to support AI capabilities on limited hardware.
Netflix’s Distributed Counter Abstraction: Delves into Netflix's Distributed Counter Abstraction, a system that enables high-throughput, low-latency counting within distributed applications.
Top 50 System Design Terminologies You Must Know: Outlines essential system design terms covering key concepts like scalability, microservices, CAP theorem, sharding, and more.
📖Open Access Book | Architectural Metapatterns by Denys Poltorak: Delves into over a hundred architectural patterns and structures, such as monoliths, layers, services, proxies, orchestrators, and more.
🧠Expert Insight📚
Here’s an excerpt from “Chapter 4: Domain Decomposition" in the book, The Art of Micro Frontends - Second Edition by Florian Rappl, published in October 2024.
Principles of DDD
The idea of DDD was first popularized by Eric Evans. In his book, he describes the basic pillars that form DDD, according to his vision. While the book certainly has a lot of truth to it, the entire army of ideas was probably rarely—if ever—realized in real-world projects. Let’s try to distill the most important
ideas for our use in micro frontends.
When we refer to DDD in the context of micro frontends, we will not include parts such as value objects or the need for a ubiquitous language. Instead, we almost exclusively take DDD as a blueprint to help us with the following two things:
Defining micro frontends with clear boundaries
Coming up with a strategy to establish these boundaries
While DDD uses the word modules, which was back then an alias for packages, we will refer to this unit as a micro frontend. The other thing that DDD introduces is a so-called bounded context. Finally, DDD defines a context map to make sense of it. But let’s back off and look at each area separately.
Modules
A module serves as a container for a specific set of functionalities in your application. For a web application, this could relate to a full page or parts of a page. For instance, a module dealing with the order process could be responsible for showing a cart symbol on the pages of a web shop, such as the product catalog or product details.
As mentioned, a module in DDD is usually what we will bring to the table in the form of a micro frontend. Nevertheless, keeping to a general notation here makes sense; after all, this helps us to see that good architectures rarely have anything to do with specific implementations but actually would work in multiple variants. In micro frontends, the functionality will be mostly designed around components.
A module is, however, a part of the full problem domain, focused on a specific area (or subdomain). The general design principles for modules are low coupling and high cohesion. As such, a micro frontend should represent a single unit to solve one problem without relying on any other micro frontend directly.
In reality, we will be tempted to rely on other micro frontends to simplify the code. The one strong advice here is to avoid doing that, as the immediate simplification will usually backfire in a more complicated and less flexible solution later. When we start looking at the different architectural patterns later in Chapter 7 onward, we’ll see how to decouple the micro frontends.
To help us figure out what could be part of a module, DDD introduces the theoretical concept of a bounded context.
Bounded context
A bounded context is used to define the boundaries of the functionality of a subdomain. This is an area where only the functionality from a certain domain makes sense.
While this may initially seem similar to a module, it is actually quite different. Multiple modules live within the same bounded context. The bounded context is an umbrella connecting them and has nothing to do with runtime considerations.
Bounded contexts are also broader than modules as they contain both unrelated concepts and shared concepts. Naturally, this will result in some overlap and duplication between different bounded contexts.
The following diagram illustrates the relationship of two bounded contexts within an example problem domain:
Figure 4.1 – Relation of two bounded contexts in an example problem domain
How we split a bounded context into modules is up to us. In the end, however, a more critical question is, what are the bounded contexts in our problem domain? There is no blueprint here, but a nice way to visualize and think about contexts generally is in the form of a context map.
Context map
A context map is a useful tool to illustrate the involved contexts of a system, including their connections. Instead of reusing objects from other contexts, a transformation defined by the context map should be used to always create domain-specific objects.
For our design decisions, a context map can be helpful to see where sharing occurs and how to still produce isolated micro frontends. To do this, we need to first identify these self-contained domains. This is where two principal ways come into play: strategic domain design and—as an alternative—tactical design. Let’s look at both.
Strategic domain design versus tactical design
While strategic domain design helps us to extend knowledge of a problem domain and come up with useful guidelines, tactical design tries to come up with design patterns and building blocks that form a system. In other words, strategic domain design identifies the different domains and the communication between them, while tactical design is all about structuring these domains.
In our micro frontend space, we have the choice of leaving the tactical design to the implementers of the micro frontends, giving them some guidance, or predefining a structure that needs to be followed already. We will see later on how these architectural boundaries can actually be decided.
In contrast, strategic domain design is helpful for decomposing a full problem domain into smaller (sub) domains. Starting with a full problem domain, we derive the individual subdomains and extract their bounded contexts. The relationship between the contexts is then captured in a context map. The following diagram shows this theoretical process:
Figure 4.2 – The idealized process of deriving a full domain decomposition from a given problem domain, including a working context map
The Art of Micro Frontends - Second Edition was published in October 2024. Packt library subscribers can continue reading the entire book for free or you can buy the book here!
Get the eBook for $29.99 $20.98
🛠️Useful Tools⚒️
Aide: An open-source, AI-native IDE that proactively supports developers with context-aware code edits, error fixes, and easy rollbacks.
Arch: An open-source prompt gateway that helps build scalable, secure AI apps with prompt safeguards, API triggers, and built-in monitoring.
Sulie: An open-source platform for advanced time series forecasting with the Mimosa foundation model, offering zero-shot and fine-tuned predictions.
That’s all for today.
We have an entire range of newsletters with focused content for tech pros. Subscribe to the ones you find the most useful here.
If your company is interested in reaching an audience of developers, software engineers, and tech decision makers, you may want to advertise with us.
If you have any suggestions or feedback, or would like us to find you a learning resource on a particular subject, leave a comment below!