Integration with messaging: Command messages and Document messages

Abstract: although the concept of document message and command message is quite simple, it’s usual to see document messages used for everything.

At the highest level, integration is about communicating different applications. This communication can be performed to exchange data or functionality.
If you are doing the integration via messaging, you’ll use messages to communicate applications.

Document messages
A document message is used if the purpose of the integration is to exchange data. The most typical document messages type is an Xml document representing a data structure.

Command messages
If the purpose is to exchange functionality (that is, calling a remote method asynchronously) a command message is used. Command messages are, for example, SOAP requests. A SOAP request contains the name of the method called and the parameters needed to call that method.

Why am I pointing to such an obvious description of integration/document messages/command messages? --> because I’ve seen in many places the misuse of this concept of document vs. command.
The concepts of integration, messaging and asynchronous are relatively new, or at least, relatively popular. Most of developers have learnt to do messaging in a data interchange fashion. As a result, document messages are being used for everything, including for functionality integration.

Let’s see an example: messages to create and update records, for example, Customers:

Common practice, not very elegant:
Use a single document schema that contains the customer data. Send messages to a different endpoint for creation or update. The receiver application knows what to do with the message because it knows where it has been received.

<Customers>
<Customer id=”1234”>
<Name>Foo</Name>
<!-- more data -->
</Customer>
<Customers>

Why is this not very elegant? --> Because the message itself does not describe the purpose. The purpose is in the context. Without the context, the message has no meaning. (Agent Smith said, “Without a purpose, we would not exist” :-)

Another common practice, even worse:
Use two different document schemas, which are very similar. They contain the same data, but they are slightly different.

Document message for creation:
<CreateCustomers>
<Customer id=”1234”>
<Name>Foo</Name>
<!-- more data -->
</Customer>
</CreateCustomers>

Document message for update:
<UpdateCustomers>
<Customer id=”1234”>
<Name>Foo</Name>
<!-- more data -->
</Customer>
</UpdateCustomers>

Why is this a bad practice? --> Ok, you have two schemas for two purposes, but they contain the same data, the same structure. You can reuse schemas via Xsd Import or Xsd Include, but it’s a workaround, not a good solution.

I've seen ever entire industry-oriented document specifications with lots of almost-equal schemas for many different purposes. So you have the same Customer Name field repeated any time a name of a customer is needed... you can imagine the Xsd Import dependency tree is 5-7 levels deep.

Good practice:
In my honest opinion, you should use document messages for data, and command messages for operations. Include parameters in your command message for the values. If your operation a bunch of data, include the document message inside the command message (just as SOAP does!). So the command message is just an envelope for the document message.

Document message for customers:
<Customer id=”1234”>
<Name>Foo</Name>
<!-- more data -->
</Customer>

Command message for operations with customers:
<CustomerActionEnvelope>
<Action>CreateCustomer</Action>
<Parameters>
<!-- insert here the full customer document message -->
<Parameters>
<CustomerActionEnvelope>

In this way, data is separated from meta-data (at schema level) and dependencies are reduced.

If you think this is interesting, go to https://www.eaipatterns.com for a deep explanation of Command Message and Document Message from the patterns point of view.