Reading Time: 10 minutes

The Mule 4 Beta release has a lot of new and improved functionality such as DataWeave and a refreshed Anypoint Studio experience, but we’ve also been busy under the hood making internal improvements to Mule runtime. In this series of posts, we’ll give a behind the scenes insight into what we have changed under the hood and why, along with the lowdown on what users need to know about the changes from an application design perspective.

This first post covers the changes to the structure of the Mule Message (specifically immutability and message collections), responsible for ferrying payloads and metadata through your flow. I’ll explain in detail what the major changes we’ve made in Mule 4 Beta are, and how you should think about them when building integrations.

latest report
Learn why we are the Leaders in API management and iPaaS

In my next post, I will go into detail on inbound and outbound properties in Mule Messages, as well as variables and other changes.

The Status Quo

mule 4 beta message
Mule Message structure in Mule 2 & Mule 3

The above diagram shows the structure of Mule Message in Mule 3. The main components of the Message were the payload and two sets of properties: inbound and outbound. Inbound properties were populated by inbound endpoints, while outbound properties could be set by the user in their flows and would then be sent by outbound endpoints. Inbound and outbound attachments operated in the same way as message properties, but were used for SOAP and email attachments along with HTTP multipart messages.

Not technically part of the Message in Mule 3 – but important to mention here – are the flow and session variables which can be used and manipulated via the Mule Expression Language and dedicated components and serve to store temporary user state during an integration.

This structure is almost unchanged since early versions of Mule before the advent of operation-based connectors.

Prioritizing Improvements

The Mule Message and how it’s used in Flows, was one of the areas we wanted to ensure we made significant improvements to with Mule 4 Beta. So, we gathered a significant amount of user feedback, and took into account both the new operation-based connectors and our own goals to improve internal cohesiveness and maintainability.

I’ll walk through each of the areas where we’ve made significant changes, specifically highlighting the impact each of these has on how you design applications with the beta

Immutability

The advantages of immutable objects are well understood, though their use has only recently become more prevalent as part of the gradual shift towards more functional programming. Two of the key advantages of the use of immutable objects are their inherent ‘thread-safeness’ and ‘share-freely’ attributes. The disadvantages are that construction of objects can be somewhat more complex and mutation of existing objects requires the creation of new instances and associated garbage collection. In Mule 3, and all previous versions of Mule, both there the Event and Message were mutable.

The ‘thread-safeness’ and ‘share-freely’ attributes of immutable objects are extremely valuable given the Mule runtime is multi-threaded and branched execution is typical in the majority of integrations. These attributes enable us to avoid defensively copying the Message and prevent potential concurrency issues. In Mule 4 Beta, we mitigate the disadvantages of immutable objects by the use of the ‘Builder Pattern’. Subsequently, given these objects are short-lived, any additional garbage collection has very minimal overhead with modern JVM’s.

With both the Message and Event object now immutable in Mule 4 Beta, we created builder implementations for each that helped clean up the proliferation of constructors that had appeared during the runtime’s evolution. Implementations are now private to the builder implementation, and the builders are exposed via their respective interfaces, as can be seen in the example below:

Message.builder().value("<foo/>").mediaType(MediaType.XML).build()
Message.builder(existing).value("newValue").build()

Impact on Application Design

The changes in object mutability do not impact application design. However, it is worth noting that you cannot mutate the message payload, attributes or any variables using DataWeave expressions in Mule 4 Beta.

Messages Collections

We have continuously received feedback that we need to improve how collections of Mule messages, resulting from aggregation, were represented and used in Mule. The primary issue here was that a Message collection was both a collection of Messages and a Message at the same time, which made it a challenge to work with and resulted in inconsistent behavior.

We resolved this by treating a collection of messages as a Message with a list of messages as its payload, rather than as a sub-type of Message. This greatly simplifies things, as message creation and transformation is now consistent with all other payload types.

Along with improved DataSense support in Mule 4 Beta, working with collections of Messages should now be a breeze.

Impact on Application Design

If you are designing a new integration with Mule 4 Beta, there isn’t anything specific to take into account as the handling of message collections is now consistent with the handling of other payload types and will be fully visible via DataSense. You may need to make some changes to your application if you are migrating an existing application from Mule 3 that use Messages collections.

Summary

I hope this blog has served to both provide some context and motivation around the changes to the Message structure in Mule 4 beta, but also given you some practical advice in terms of how to understand how you should think about designing Mule 4 beta applications taking these changes into account. Keep your eyes out for my next post, where I will discuss additional changes, including changes to inbound and outbound properties.

Ready to Get Started? Check Out Resources on Mule 4 Beta!