<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oliver Libutzki</title>
    <description>The latest articles on DEV Community by Oliver Libutzki (@olibutzki).</description>
    <link>https://dev.to/olibutzki</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F65188%2Fa823c3d6-1a55-493f-93a2-414d86ef7dc1.jpeg</url>
      <title>DEV Community: Oliver Libutzki</title>
      <link>https://dev.to/olibutzki</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olibutzki"/>
    <language>en</language>
    <item>
      <title>archifacts is launched</title>
      <dc:creator>Oliver Libutzki</dc:creator>
      <pubDate>Sun, 12 Sep 2021 13:52:55 +0000</pubDate>
      <link>https://dev.to/olibutzki/archifacts-is-launched-26il</link>
      <guid>https://dev.to/olibutzki/archifacts-is-launched-26il</guid>
      <description>&lt;p&gt;I am very happy to announce the launch of &lt;em&gt;archifacts&lt;/em&gt; - a library which helps you to extract the building blocks and relationships between them out of your Java or Kotlin application's bytecode.&lt;/p&gt;

&lt;p&gt;In this blog post I'd like to explain the motivation for creating this library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tackling outdated documentation
&lt;/h2&gt;

&lt;p&gt;Some weeks ago I stumbled upon this tweet by Tudor Girba.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1427342753952899080-704" src="https://platform.twitter.com/embed/Tweet.html?id=1427342753952899080"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1427342753952899080-704');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1427342753952899080&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;When you crawl through the comments you quickly realize that most of the discussions are about the challenge to keep documentation up-to-date. In my current project we ran into this trap as we created a very extensive documentation which was not able to keep pace with the application's progress.&lt;/p&gt;

&lt;p&gt;I do not say it's impossible to keep your software system and its documentation in sync, if they are independent artifacts, but it requires a high amount of discipline and effort.&lt;/p&gt;

&lt;p&gt;I recommend to document the architectural concepts by hand and to derive the application's concrete building blocks automatically.&lt;/p&gt;

&lt;p&gt;In general you have two options: You can model your application on a higher abstraction layer and generate code and documentation out of this model. Model-driven software engineering (MDSE) and DSLs are are promising approach to implement this strategy.&lt;/p&gt;

&lt;p&gt;While this is a good idea in the first place you rarely model a whole application. Most often some stubs are generated which are implemented using a General Purpose Language (GPL) like Java, C# or Python. Therefore you cannot be sure that all the information is contained in the model... and that results in an incomplete documentation which is as bad as an outdated documentation.&lt;/p&gt;

&lt;p&gt;In my opinion the most promising approach to document the actual behaviour of a system is to extract it from its foundation: the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing archifacts
&lt;/h2&gt;

&lt;p&gt;This is where &lt;em&gt;archifacts&lt;/em&gt; kicks in. It analyzes your Java or Kotlin application's bytecode and builds an architecture model. Having this model in place you can use it to enhance your documentation by generating information about your modules, building blocks and relationships between them.&lt;/p&gt;

&lt;p&gt;In this very first release &lt;em&gt;archifacts&lt;/em&gt; ships integrations for &lt;em&gt;Spring Framework&lt;/em&gt;, &lt;em&gt;Axon Framework&lt;/em&gt; and &lt;em&gt;jMolecules&lt;/em&gt;, a library which helps you to express your architectural concepts directly in the source code.&lt;/p&gt;

&lt;p&gt;There is also some very basic support for generating documentation using AsciiDoc and Simon Brown's &lt;a href="https://c4model.com/" rel="noopener noreferrer"&gt;C4 model&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;archifacts&lt;/em&gt; stands on the shoulders of a giant: &lt;a href="https://www.archunit.org/" rel="noopener noreferrer"&gt;ArchUnit&lt;/a&gt; and its fabulous Core API to extract the concepts from the bytecode.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1421848177142026245-559" src="https://platform.twitter.com/embed/Tweet.html?id=1421848177142026245"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1421848177142026245-559');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1421848177142026245&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  Moduliths similarities
&lt;/h2&gt;

&lt;p&gt;Conceptually, there a lot of similarities to &lt;a href="https://github.com/odrotbohm/moduliths" rel="noopener noreferrer"&gt;Moduliths&lt;/a&gt;.&lt;br&gt;
&lt;em&gt;Moduliths&lt;/em&gt; helps you to build modular Spring Boot applications which are preferred to be deployed as a single unit. Like &lt;em&gt;archifacts&lt;/em&gt; &lt;em&gt;Moduliths&lt;/em&gt; uses &lt;em&gt;ArchUnit&lt;/em&gt; to enforce certain architectural constraints and - based on some rules - it's able to identify the application's building blocks.&lt;/p&gt;

&lt;p&gt;Although I'm convinced that &lt;em&gt;Moduliths&lt;/em&gt; is a great starting point for building modular Spring Boot based applications, it was not the best choice for my use case. &lt;em&gt;Moduliths&lt;/em&gt; has some impacts and expections regarding the application's structure. It has advanced semantics what a module is and which rules are enforced.&lt;/p&gt;

&lt;p&gt;After providing some issues and PRs for &lt;em&gt;Moduliths&lt;/em&gt; I decided that it's more efficient to build a library which is completely agnostic of any other runtime technology like Spring Boot.&lt;/p&gt;

&lt;p&gt;I do not want to place &lt;em&gt;archifacts&lt;/em&gt; as a competitor to &lt;em&gt;Moduliths&lt;/em&gt;. It has a slightly different scope and maybe it makes sense to join forces some day.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started
&lt;/h2&gt;

&lt;p&gt;If you want to see &lt;em&gt;archifacts&lt;/em&gt; in action as quick as possible check out the &lt;a href="https://github.com/archifacts/archifacts/tree/main/examples/jmolecules-spring-data-jpa" rel="noopener noreferrer"&gt;jmolecules-spring-data-example&lt;/a&gt;. It generates some&lt;br&gt;
C4 diagrams and a textual architecture overview for a jMolecules example.&lt;/p&gt;

&lt;p&gt;Please keep in mind that &lt;em&gt;archifacts&lt;/em&gt; is in a very very early state, but I already published the first release to Maven Central, so everyone can use it and give feedback. Any contributions are highly welcome. To get in touch you can use &lt;a href="https://github.com/archifacts/archifacts" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and/or follow the project on &lt;a href="https://twitter.com/archifacts_org" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I really hope that &lt;em&gt;archifacts&lt;/em&gt; will come in handy for some other projects.&lt;/p&gt;

&lt;p&gt;One last shoutout to &lt;a href="https://twitter.com/NilsEhmke" rel="noopener noreferrer"&gt;Nils Ehmke&lt;/a&gt; for all the valuable discussions, reviews and contributions. Thank you!&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>documentation</category>
      <category>archunit</category>
      <category>java</category>
    </item>
    <item>
      <title>Do you really need an API?</title>
      <dc:creator>Oliver Libutzki</dc:creator>
      <pubDate>Sun, 04 Apr 2021 20:14:50 +0000</pubDate>
      <link>https://dev.to/olibutzki/do-you-really-need-an-api-2pk7</link>
      <guid>https://dev.to/olibutzki/do-you-really-need-an-api-2pk7</guid>
      <description>&lt;p&gt;"Low coupling, high cohesion", "information hiding": Well known design principles. Nevertheless, they are not taken seriously in many software architectures, especially when it comes to the interaction between the frontend and the backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  APIs are valuable to hide information
&lt;/h2&gt;

&lt;p&gt;By providing an API systems decide which information they expose to the outside world and which information they keep secret (Information hiding).&lt;/p&gt;

&lt;p&gt;Why is that important? Because the broader an API is the more expensive it is to maintain. Think about the extreme of exposing every implementation detail. Every change in the system might break the clients which use the code. That's the reason why we strive for having small APIs. I wrote a &lt;a href="https://dev.to/olibutzki/why-event-sourcing-is-a-microservice-anti-pattern-3mcj"&gt;post&lt;/a&gt; about this topic in the context of Event Sourcing.&lt;/p&gt;

&lt;p&gt;Regardless of its size an API prevents us from evolving our system in a free manner. We always have to document the API carefully and consider not to break our clients. Changes have to be introduced in a backward compatible way or we have to align the deployments of our systems which quickly ends up in a deployment monolith hell. &lt;/p&gt;

&lt;h2&gt;
  
  
  API as product
&lt;/h2&gt;

&lt;p&gt;But why do systems provide so many APIs, if it's so hard to maintain them? One reason might be that the API is the system's Unique Selling Point. The API is the product und you earn money by providing this API. In this case it's worth the efforts to document it, to use techniques like hypermedia and care about backward compatibility. Your clients will appreciate it and your API product shines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separation of frontend and backend
&lt;/h2&gt;

&lt;p&gt;I argue that those API products are rare. Way more often the existence of a broad API is a sign for badly chosen boundaries - a violation of the "Low coupling - High cohesion" principle.&lt;/p&gt;

&lt;p&gt;While this investigation applies to backend-to-backend communication, too, I would like to focus on the frontend. I question that we need an API to connect the backend and the frontend. &lt;/p&gt;

&lt;p&gt;It's natural that the backend and the frontend are highly cohesent, because whenever some new data needs to be displayed on the frontend the backend needs to be adjusted. So why do we try to decouple them by putting a wall (an API) in between them?&lt;/p&gt;

&lt;p&gt;Most of the time such a design is driven by organizational or technical circumstances. There are dedicated backend and frontend teams, but I wonder if the overhead of maintaining an API is always taken into account when deciding to separate the teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  The desire for using client-side rendering
&lt;/h2&gt;

&lt;p&gt;Another driver is the desire to implement the frontend with a modern Javascript UI library like Angular, React or Vue.js. In contrast to server-side rendered (SSR) approaches these libraries render the view at client-side (CSR) in the browser and rely on services (REST, GraphQL,...) provided by the backend to retrieve data and perform actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self contained and CSR are no contradiction
&lt;/h2&gt;

&lt;p&gt;Although I think that SSR is highly underrated these days, I can understand that the frontend requirements might be addressed better by a modern Javascript library. &lt;br&gt;
But... using such a library does not necessitate an API! Think about delivering the service as a &lt;a href="https://scs-architecture.org/"&gt;self-contained system&lt;/a&gt;, including the backend AND the frontend. Sure, you have a technology and environment break as the backend code is executed server-side and the frontend code is executed in the user's browser. This break requires the usage of HTTP in order to synchronize both environments.&lt;/p&gt;

&lt;p&gt;I call this a bridge rather than an API as you can evolve the backend services hand in hand with the frontend. There is no need to document an API carefully or to deal with breaking changes, because there is just one client out there. And this client is well-known, because it's located in the very same system. The consequence is that the backend and frontend are always deployed as a whole and those documentation and compatibility challenges disappear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Technology should not be the driver for system design. Regarding the interaction between the backend and the frontend take the requirements into account and decide if you want to go for a monolithic frontend or self-contained systems. "Low coupling - high cohesion" is a powerful guideline!&lt;/p&gt;

&lt;p&gt;If you decide for a self-contained system it's up to you to choose a server-side or client-side rendering approach. Although CSR and SPA (Single Page Application) often are lumped together you can use CSR while still having a per-module frontend.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;I had the idea of writing this post while listening to the &lt;a href="https://www.heise.de/developer/artikel/Episode-82-APIs-was-zeichnet-sie-aus-und-was-sind-die-Herausforderungen-5068881.html"&gt;SoftwareArchitekTOUR Podcast - Episode 82 (German)&lt;/a&gt; with &lt;a href="https://twitter.com/stilkov"&gt;Stefan Tilkov&lt;/a&gt; and &lt;a href="https://twitter.com/ewolff"&gt;Eberhard Wolff&lt;/a&gt;. Thanks for the inspiration!&lt;/p&gt;

&lt;p&gt;Good resources to get deeper into self-contained systems and micro frontends:&lt;br&gt;
&lt;a href="https://scs-architecture.org/"&gt;Self-Contained Systems&lt;/a&gt;&lt;br&gt;
&lt;a href="https://martinfowler.com/articles/micro-frontends.html"&gt;Micro Frontend&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>spa</category>
      <category>ssr</category>
      <category>microfrontend</category>
    </item>
    <item>
      <title>Why Event Sourcing is a microservice communication anti-pattern</title>
      <dc:creator>Oliver Libutzki</dc:creator>
      <pubDate>Fri, 28 Jun 2019 11:26:22 +0000</pubDate>
      <link>https://dev.to/olibutzki/why-event-sourcing-is-a-microservice-anti-pattern-3mcj</link>
      <guid>https://dev.to/olibutzki/why-event-sourcing-is-a-microservice-anti-pattern-3mcj</guid>
      <description>&lt;p&gt;Event-driven architectures in general and Event Sourcing in particular gain traction in the last couple of years. This trend is caused by the fact that we strive after building modular systems which are resilient und scalable. &lt;em&gt;Microservices&lt;/em&gt; is the term which is used in this context quite often. In my opinion microservices are just one way to implement a Bounded Context. The heart of a modular system are the boundaries of a module and the most promising idea how to identify these boundaries is the &lt;a href="https://en.wikipedia.org/wiki/Domain-driven_design#Strategic_domain-driven_design" rel="noopener noreferrer"&gt;Strategic Design&lt;/a&gt; introduced by Eric Evans' Domain Driven Design. It helps you to identify/discover your modules with their boundaries (&lt;a href="https://martinfowler.com/bliki/BoundedContext.html" rel="noopener noreferrer"&gt;Bounded Context&lt;/a&gt;) and describes the way how these Bounded Contexts are related to each other (Context Map).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I will presuppose some foreknowledge about certain terms as I do not want to explain them for the thousandth time. I decided to link to the explanations of &lt;a href="https://microservices.io/" rel="noopener noreferrer"&gt;microservices.io&lt;/a&gt;, &lt;a href="https://en.wikipedia.org" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt; or &lt;a href="https://martinfowler.com/bliki/" rel="noopener noreferrer"&gt;Martin Fowler's Bliki&lt;/a&gt;, so it's up to you do dive deeper into a certain topic, if you feel uncomfortable with your knowledge.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Domain Events as the heart of the Ubiquitous Language
&lt;/h1&gt;

&lt;p&gt;Although not explicitly mentioned in Eric's book Domain Events facilitate the idea of the DDD concepts quite well. Techniques like Alberto Brandolini's &lt;a href="https://en.wikipedia.org/wiki/Event_storming" rel="noopener noreferrer"&gt;Event Storming&lt;/a&gt; shift the focus on events from a technical to a organizational / business level. We do not talk about some UI layer events like a &lt;em&gt;ButtonClickedEvent&lt;/em&gt;, but about Domain Events which are part of the business domain and which are spoken and understood by the business experts. These Domain Events are first-class concepts and provide a great way to form the &lt;a href="https://martinfowler.com/bliki/UbiquitousLanguage.html" rel="noopener noreferrer"&gt;Ubiquitous Language&lt;/a&gt; which all participants (domain experts, developers,...) agree on.&lt;/p&gt;

&lt;h1&gt;
  
  
  Domain Events used for cross-boundary communication
&lt;/h1&gt;

&lt;p&gt;Domain Events can be used for facilitating the communication between Bounded Contexts. Let's assume we have an online shop with three Bounded Contexts: Order, Delivery, Invoice.&lt;/p&gt;

&lt;p&gt;A Domain Event of the Order context is &lt;em&gt;Order accepted&lt;/em&gt;. The Invoice as well as the Delivery context is interested in the occurence of this event as it causes some internal processes to be started.&lt;/p&gt;

&lt;h1&gt;
  
  
  The decoupling myth
&lt;/h1&gt;

&lt;p&gt;The usage of Domain Events helps you to develop decoupled modules. Modules might be offline temporarily. Domain Events do not care about unavailable modules, they describe something that happened in the past. It's up to the other modules how fast they process the events. What you get is a resilient system by design.&lt;/p&gt;

&lt;p&gt;Beside temporal decoupling Domain Events promise another advantage, at least at the first glance:&lt;br&gt;
The Order context does not have to know that the Invoice and Delivery context listen to its events. Actually it even doesn't need to know that those contexts exist.&lt;/p&gt;

&lt;p&gt;That's cool, but the challenging part is the event payload. Which data do put into the event?&lt;/p&gt;
&lt;h1&gt;
  
  
  The simple answer: Event Sourcing!
&lt;/h1&gt;

&lt;p&gt;Events are useful, so why not giving them as much power (and responsibility) as possible. That's the basic idea of &lt;a href="https://microservices.io/patterns/data/event-sourcing.html" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt;. You do not store the state of an aggregate by updating its data (CRUD) but by applying an event stream.&lt;/p&gt;

&lt;p&gt;Beside that fact that you can replay events to rebuild the application state, one great feature of Event Sourcing is that you get a complete and reliable audit log for free. So when such an audit log is required, Event Sourcing should definitely taken in account while evaluating the persistence strategy.&lt;/p&gt;
&lt;h1&gt;
  
  
  Is Event Sourcing just a persistence strategy?
&lt;/h1&gt;

&lt;p&gt;You might wonder why I came from Domain Events straight to persistence strategy as these concepts obviously work at different layers / abstraction levels.&lt;/p&gt;

&lt;p&gt;... and that's my point: Event Sourcing is a local decision made by a single Bounded Context! The events should not be exposed to the outside world! Other Bounded Contexts do not know about each other's persistence strategy and therefore they don't know and don't care, if another Bounded Context uses Event Sourcing.&lt;/p&gt;

&lt;p&gt;If you use Event Sourcing at global scale, you expose your persistence layer.&lt;/p&gt;

&lt;p&gt;Your persistence becomes your public API. Every time a Bounded Context adjusts its persistent data, we have to deal with a public API change.&lt;/p&gt;

&lt;p&gt;I'm pretty sure everyone agrees that it's a bad idea that different Bounded Contexts &lt;a href="https://microservices.io/patterns/data/shared-database.html" rel="noopener noreferrer"&gt;share data in a (relational) database&lt;/a&gt; because of development und runtime coupling. But where is the difference? &lt;/p&gt;

&lt;p&gt;There is none. It doesn't matter if we share events or database tables. In both cases we share our persistence details.&lt;/p&gt;
&lt;h1&gt;
  
  
  There is a way out
&lt;/h1&gt;

&lt;p&gt;I still argue that Domain Events are a perfect fit for the communication between Bounded Contexts, but these events shall not correspond to the events used for Event Sourcing. &lt;/p&gt;

&lt;p&gt;My proposed solution is the logical consequence: Regardless whether you use a CRUD or an Event Sourcing approach for persistence you publish Domain Events to a global event store. These Domain Events are your Bounded Context's public API. If you prefer the usage of Event Sourcing in your Bounded Context you store these events in a local event store which only accessible from this Bounded Context &lt;/p&gt;
&lt;h1&gt;
  
  
  The freedom of choice
&lt;/h1&gt;

&lt;p&gt;Having dedicated Domain Events in your public API opens up the possibility to decide how to model these events. You are not restricted to the layout which is predefined by the Event Sourcing events.&lt;/p&gt;

&lt;p&gt;You have two options for each occurrence of a "real world event":&lt;/p&gt;
&lt;h2&gt;
  
  
  Open Host Service with Published Language
&lt;/h2&gt;

&lt;p&gt;Publish exactly one domain event which contains all the data which might be needed by other Bounded Contexts. In DDD terminology one would call this an Open Host Service with a Published Language. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdy91vg9m95smta4lvt50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdy91vg9m95smta4lvt50.png" alt="Open Host Service with Published Language"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The occurrence of the real world event &lt;em&gt;Order accepted&lt;/em&gt; leads to one published Domain Event &lt;em&gt;OrderAccepted&lt;/em&gt;. The payload of this event contains all the data which Order expects other Bounded Context's to be interested in... so hopefully the Invoice and the Delivery contexts find all the information they need.&lt;/p&gt;
&lt;h2&gt;
  
  
  Customer/Supplier
&lt;/h2&gt;

&lt;p&gt;Publish multiple dedicated Domain Events, one for each event consumer. You have to discuss each particular Domain Event with exactly one other party (the consumer) and don't have to define a shared model. DDD calls this relationship Customer/Supplier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq5r71f6llsvom21z18oo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq5r71f6llsvom21z18oo.png" alt="Customer/Supplier"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The occurrence of the real world event &lt;em&gt;Order accepted&lt;/em&gt; leads to one published Domain Event per consuming Bounded Context: &lt;em&gt;InvoiceOrderAccepted&lt;/em&gt; and &lt;em&gt;DeliveryOrderAccepted&lt;/em&gt;. Each Domain Event contains exactly the data which is requested by the consuming context.&lt;/p&gt;

&lt;p&gt;I do not want to discuss the pros and cons of the two options. I just want to highlight that you are free to choose the number of Domain Events and their payload.&lt;/p&gt;

&lt;p&gt;This is a great advantage you should not underestimate, because you can decide how to evolve your Bounded Context's API and are not committed to the events you need for Event Sourcing.&lt;/p&gt;
&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Exposing persistence details to the outside world is a well-known anti-pattern. When talking about persistence we think about database tables in the first place, but I explained why the events used for Event Sourcing are just another way how to persist data. Therefore exposing these events is a anti-pattern as well.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-784691906005635072-812" src="https://platform.twitter.com/embed/Tweet.html?id=784691906005635072"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-784691906005635072-812');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=784691906005635072&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Event Sourcing is powerful, if it's used in an appropriate (local) way. At first glance it seems to be the silver bullet for event-driven architectures, but if you look in deeper, you realize that it might lead you to a tightly coupled (distributed) system... and that's not your aim, for sure.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;Beside my personal experience I got a lot of inspiration from different abstracts and conference talks. I would like to highlight the talk &lt;em&gt;Event-based Architecture and Implementations with Kafka and Atom&lt;/em&gt; by Eberhard Wolff. Especially the chapters &lt;a href="https://youtu.be/Ecg7lvvm8aU?t=1178" rel="noopener noreferrer"&gt;Event Sourcing&lt;/a&gt; and &lt;a href="https://youtu.be/Ecg7lvvm8aU?t=655" rel="noopener noreferrer"&gt;Whats's in the event?&lt;/a&gt; are highly relevant in the context of this blog post. The online shop example I chose is inspired by this talk.&lt;/p&gt;

&lt;p&gt;There are some other resources you can consult if you would like to get some additional information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.innoq.com/en/blog/domain-events-versus-event-sourcing/" rel="noopener noreferrer"&gt;Domain Events vs. Event Sourcing&lt;/a&gt; by Christian Stettler, Blog post&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@hugo.oliveira.rocha/what-they-dont-tell-you-about-event-sourcing-6afc23c69e9a" rel="noopener noreferrer"&gt;What they don’t tell you about event sourcing&lt;/a&gt; by Hugo Rocha, Blog post&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/LDW0QWie21s?t=1259" rel="noopener noreferrer"&gt;A Decade of DDD, CQRS, Event Sourcing (CQRS/ES is NOT a top level architecture)&lt;/a&gt; by Greg Young, Conference talk&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>eventsourcing</category>
      <category>domaindrivendesign</category>
      <category>domainevents</category>
    </item>
  </channel>
</rss>
