Week 17, year 2025
- Additional explanatory material for the Deepseek Overview - A couple of months ago, my colleague Shayan Mohanty published a technical overview of the series of papers describing the deepseek AI models. He's now gone through that article, adding more explanations to make it more digestible for those of us who don't have a background in building these kinds of models. [Martin Fowler]
Week 16, year 2025
- 10 problems that Event Sourcing can help solve for you - I recently ended up in a discussion on when Event Sourcing is the right architecture style or not. As the universal answer to this question tends to be "it depends," I started thinking about the typical problems where I would use Event Sourcing. I came up with a couple of them, some more functional and some more technical. Here's a summary of those thoughts. [Event Store blog]
- AutoMapper and MediatR Licensing Update - In my last post, I shared the news that I've decided to take a commercialization route for AutoMapper and MediatR to ensure their long-term success. While that post was heavy on the motivation, it was intentionally light on the details. I did share that I wanted to be [Jimmy Bogard]
- Announcing Axon Framework 5: Configuring Axon made easy. - Today we are officially launching the first milestone of Axon Framework 5.0.0, and needless to say, everyone here at AxonIQ is excited about the new release! For those who are unaware, Axon Framework has long been the default go-to solution for implementing event-driven microservices with Java and JVM-based systems. Now, with the release of Axon Framework 5, we aim to broaden the Framework’s capabilities while reducing complexity for both veterans and newcomers alike. We think that the best way to accomplish this (and to give the community time to adapt to the new APIs and paradigms) is to deliver the full release in milestones — continuing to make event sourcing easy! [AxonIQ Blog]
- Announcing Axon Server 2025.0: Connecting to Axon Server made easy - AxonIQ is a company known for making Event Sourcing easy. This is why we’re happy to announce the launch of Axon Server 2025.0, which now includes robust support for bi-directional HTTP connections for all of your event-sourced applications. This literally means that you can now use any programming language to interact with Axon Server. This capability was originally called AxonIQ Synapse, but its previous implementations required developers to download an additional executable to run along with their Axon Server. Now, a fully embedded and configurable HTTP server is available within Axon Server 2025.0, so let’s talk about the implications of what that really means. [AxonIQ Blog]
- Guiding an LLM for Robust Java ByteBuffer Code - AI editors like Cursor can generate code with remarkable speed using LLMs, handling boilerplate and providing functional snippets for various tasks. However, when building robust systems, functional correctness is only the starting point. Code must also be safe, predictable, maintainable, and free from subtle side effects. Unmesh Joshi demonstrates, through a dialogue between a developer and an LLM, how expert guidance is crucial to transform an initial, potentially unsafe code snippet into a robust, system-ready component. [Martin Fowler]
Week 15, year 2025
Week 14, year 2025
- MediatR 12.5.0 Released - I pushed out MediatR 12.5 today: Release Notes NuGet This is mainly a regular minor release with a couple extra interesting features: Adding convenience method to register open behaviors Better cancellation token support (it's passed now everywhere including behaviors) And some other cleanup items as well. Enjoy! [Jimmy Bogard]
- I've been kidnapped by Robert Caro - I've always enjoyed reading, and for most of my life I've particularly enjoyed reading history. I've head many great things about Robert Caro's books, but was deterred by their size. Finally, with his first book newly available as an ebook, I decided to dip my toes in. The books are too good for me to escape. [Martin Fowler]
- AutoMapper and MediatR Going Commercial - Yes, another one of "those posts". But tl;dr: In order to ensure the long-term sustainability of my OSS projects, I will be commercializing AutoMapper and MediatR. I did not post this on April 1st for obvious reasons. But first a little background on how I got to [Jimmy Bogard]
- Social Media Engagement in Early 2025 - A few years ago, whenever I published a new article here, I would just announce it on Twitter, but since the Muskover its importance has declined, and now I post updates to several services. To compare engagement on these services, I've looked at reposts, likes, and replies to two dozen of my recent posts. [Martin Fowler]
- Updating yesterday's post on social media engagement - Some people asked about how many people clicked through the links on these social media posts. I've added some more to the article, partly to explain why I don't have that information, and partly to show overall source data for traffic to the site. [Martin Fowler]
Week 13, year 2025
- The role of developer skills in agentic coding - As agentic coding assistants get more capable, Birgitta Böckeler is trying them to change existing codebases. This has led to some impressive collaboration sessions, but she's needed to intervene, correct and steer all the time. In her latest post, she describes examples of these interventions, giving ideas of the types of skills we currently need to correct the tools' missteps. [Martin Fowler]
Week 11, year 2025
- New Eventuate platform APIs that support Async API: part 1 - events - New Eventuate platform APIs that support Async API: part 1 - events I recently developed a plugin for SpringWolf that configures an Eventuate service to expose an /springwolf/docs endpoint that returns an Async API document describing the messages that the service sends and receives. While implementing the plugin, however, I discovered that the existing Eventuate APIs were not well suited to exposing Async API-style metadata. For example, the messages sent by the service — and the channels to which it sent them — were not explicitly defined; instead, these details were hidden within the code This realization prompted the creation of a new set of Eventuate APIs for sending and receiving messages. The old APIs still work but only limited metadata can be generated from them. In this article, I’ll describe the new APIs for publishing and subscribing to events. A later article will describe the new APIs for commands and sagas. Let’s first look at the changes to event publishing. Event publishing Let’s first look at the old way of publishing events. After that I describe the new approach. Original event publishing API Previously, domain logic simply used the DomainEventPublisher to publish events: publicclassCustomerService{privateDomainEventPublisherdomainEventPublisher;@TransactionalpublicCustomercreateCustomer(Stringname,MoneycreditLimit){...domainEventPublisher.publish(Customer.class,customer.getId(),customerWithEvents.events);returncustomer;} As a result, the channels and event types were not explicitly defined. New event publishing API The new approach consists of defining one or more DomainEventPublisherForAggregate@Beans. A DomainEventPublisherForAggregate publishes events for a specific aggregate. Although defining DomainEventPublisherForAggregates involves more code, it explicitly defines the channels and events. The Eventuate plugin for Spring Wolf uses the DomainEventPublisherForAggregate@Beans to generate an Async API document describing the published events and their channels. Here’s the definition of a DomainEventPublisherForAggregate for the Customer aggregate: publicinterfaceCustomerEventPublisherextendsDomainEventPublisherForAggregate<Customer,Long,CustomerEvent>{} It’s injected into the CustomerService: publicclassCustomerService{privatefinalCustomerEventPublishercustomerEventPublisher;publicvoidreserveCredit(longorderId,longcustomerId,MoneyorderTotal){CustomerCreditReservedEventcustomerCreditReservedEvent=newCustomerCreditReservedEvent(customerId,orderId);customerEventPublisher.publish(customer,customerCreditReservedEvent); Finally, here is the @Bean implementation of the CustomerEventPublisher: @ComponentpublicclassCustomerEventPublisherImplextendsAbstractDomainEventPublisherForAggregateImpl<Customer,Long,CustomerEvent>implementsCustomerEventPublisher{publicCustomerEventPublisherImpl(DomainEventPublisherdomainEventPublisher){super(Customer.class,Customer::getId,domainEventPublisher,CustomerEvent.class);}} Let’s now look at the new event handling API. Subscribing to events Let’s first look at the old way of subscribing to events. After that I describe the new approach. Original event handling API Previously, event handlers were configured by defining a class that constructed DomainEventHandlers: publicclassOrderEventConsumer{publicDomainEventHandlersdomainEventHandlers(){returnDomainEventHandlersBuilder.forAggregateType("io.eventuate.examples.tram.ordersandcustomers.orders.domain.Order").onEvent(OrderCreatedEvent.class,this::handleOrderCreatedEvent)....build();}publicvoidhandleOrderCreatedEvent(DomainEventEnvelope<OrderCreatedEvent>domainEventEnvelope){... The DomainEventHandlers was then passed to a DomainEventDispatcherFactory: publicclassCustomerConfiguration{@BeanpublicOrderEventConsumerorderEventConsumer(CustomerServicecustomerService){returnnewOrderEventConsumer(customerService);}@BeanpublicDomainEventDispatcherdomainEventDispatcher(OrderEventConsumerorderEventConsumer,DomainEventDispatcherFactorydomainEventDispatcherFactory){returndomainEventDispatcherFactory.make("orderServiceEvents",orderEventConsumer.domainEventHandlers());} The Eventuate plugin for Spring Wolf can use the DomainEventDispatcher@Beans to generate an Async API document describing the subscribed to events and their channels. However, there’s no obvious way to customize the Async API document by, for example, specifying additional documentation. New event handling API The new approach is to define beans that have methods annotated with @EventuateDomainEventHandler. The annotation specifies the event handler’s subscriber ID and the channel. The event type is obtained from the method parameter. @ComponentpublicclassOrderEventConsumer{privateLoggerlogger=LoggerFactory.getLogger(getClass());privateCustomerServicecustomerService;publicOrderEventConsumer(CustomerServicecustomerService){this.customerService=customerService;}@EventuateDomainEventHandler(subscriberId="OrderEventConsumer",channel="io.eventuate.examples.tram.ordersandcustomers.orders.domain.Order")publicvoidhandleOrderCreatedEvent(DomainEventEnvelope<OrderCreatedEvent>domainEventEnvelope){OrderCreatedEventevent=domainEventEnvelope.getEvent();customerService.reserveCredit(Long.parseLong(domainEventEnvelope.getAggregateId()),event.orderDetails().customerId(),event.orderDetails().orderTotal());} The Eventuate plugin for Spring Wolf can search the application context for @Beans that have methods annotated with @EventuateDomainEventHandler. Moreover, in the future, it will support additional annotations that allow you to customize the generated Async API document. Show me the code The Eventuate Spring Wolf repository contains some example Async API docs The development branch of the eventuate-tram-examples-customers-and-orders repository contains an example application that uses the new APIs. What’s next A later post will describe the new APIs for sagas and command handlers. [Eventuate, Inc]
Week 10, year 2025
- Upcoming Training on Modern .NET with Vertical Slice Architecture in Frankfurt - It's training time again! I've got another training event coming up focusing on Modern .NET with Vertical Slice Architecture in Frankfurt on June 25th-26th. Also similar to last year's edition of the course is an option for either a 2-day or 3-day version. The [Jimmy Bogard]