Messages, data and types

One concern I receive quite a bit from folks new to messaging, especially those coming from SOAP and WCF land, is how to preserve the convenience of proxy classes and data contracts that can be shared amongst multiple clients. The problem comes in when looking at coupling, especially around changes in the contract and how to upgrade clients. Clemens Vasters details many of these issues in his screencast on data/contract coupling in messaging.

One thing that grounds all of this is what we consider the message as developers, and what our transport and messaging system considers to be the message. For example, the Azure REST services expose contracts as XML. XML, by itself, and JSON make for great transport formats because the underlying technology provides a fairly universally acceptable common type system. Although your language might need to bridge from your format to theirs, people standardize on ISO formats for standard primitives to maximize interoperability (and minimize serialization mistakes).

Dealing with such large XML documents from a client API can be a pain, however. XML is notoriously finicky with respect to case sensitivity, and I can’t count how many times I’ve been bitten by this when dealing with raw XML and REST APIs. We would need to assume that documentation exists, and until forms become common in REST APIs, it’s difficult to say that HATEOAS will simply solve all these problems of self-describing APIs.

Instead, we often see REST and other messaging clients, out of convenience, build DTOs as a means of representing the message. But first – what is a message? A message is just data. It’s defined by a header and body, where the header is used by the transport/messaging system and the body is ignored (picture courtesy

However, messages aren’t types. But what about sharing something like this?

public class PurchaseOrder
	private int poId_value;
	// Apply the DataMemberAttribute to the property.
	public int PurchaseOrderId
	    get { return poId_value; }
	    set { poId_value = value; }

That’s still not terrible, because underneath the covers our message is still just XML or JSON. We use this type as a description or blueprint of our message, because it’s simpler to describe our message in C# terms instead of a looser type like XML or JSON, which are more difficult to describe and use in C#. I’m ignoring dynamic types in .NET – those to me are a bit of a hack in this case. In WCF, proxy classes get generated on the client side, so we’re still not taking an assembly dependency. This isn’t available in REST or other messaging technologies, leaving clients reliant on documentation to “Get it right” – assuming that they don’t make mistakes translating raw XML or JSON into code building raw XML or JSON on the client side.

So what typically happens in a homogenous environment is that data contract assemblies are shared:


Both client and server share a contracts assembly, and use the contracts assembly as a description for how to construct and consume the raw messages.

We introduce coupling on the client side with a raw type shared across the server boundary, but it’s up to those building the system to determine if this sort of coupling introduces any potential risks. When we look at coupling, we must always balance risk. If coupling introduces low risk, it might be acceptable (assuming we’re more or less prescient in our future system’s design).

From my experience, as long as the messaging infrastructure doesn’t assume that the message is built from a type and therefore leak those concerns, this sort of model can be a nice compromise in ecosystems where types as blueprints for messages ensures safety in our message construction and consumption. It’s similar to building MVC applications around View Models – they’re a blueprint for building forms, and a means of accepting raw form POSTs. Side note – I found it hilarious that the Rails folks ran into that mass assignment security problem – it’s a problem I’ve never, ever had in MVC.

But that’s the real kicker – our messaging infrastructure can’t assume types, as the message is not the type. We might use a type as a convenience to build and consume, as we do in MVC, but ultimately, our messaging infrastructure can’t assume a type. MVC handles this quite well, with model metadata and its ModelState objects. The original request is always preserved in its raw form (dictionary of strings), but the model provided to the controller action is an approximation of that request.

It’s only when we assume that we’ve literally shared types that we’re going to slip into real type coupling, and everything that SOAP failed to deliver comes back again.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Messaging, SOA. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • This is an amazing post , i really like this. You people really wrote very well , keep posting like this , i will appriciate you for ths great post, thank you so much for this article.
    Best Pc Tablets

  • Pingback: Messages, data and types | CodingScoop |

  • Steve

    If you are using types as a blueprint for your messages that works great for the producer side of the equation. But what about the consumer? Won’t you have to include some metadata on the message to give the consumer a hint as to how to interpret the message? I assume from the above that you would consider metadata regarding the type to be too leaky.

    It seems that many .NET frameworks use the type not only for serialization at the producer and consumer, but for routing of the messages to the appropriate handler within a consumer (IHandle or similar). It seems you wouldn’t be able to do this type of routing w/o passing/sharing a hint as to the type that was encoded in the message?

  • @f974887ff60274e84f0cd039f051650a:disqus I use meta data “type” on my external events. Clients have to know the context of the information. How else would clients be able to process information correctly in their context?

  • Dale Anderson

    I’m currently looking at using pure interfaces as message types. NServiceBus supports interfaces as messages, and JSON.NET combined with ImpromptuInterface works really well for wrapping interfaces around JSON. It allows you to compose your message schemas from many simple structures.

    Requires a bit more exploration, but on the surface it seems like a really good compromise between the implicit / dynamic nature of JSON and the explicit nature of the CLR.

  • very good article, the message is personal matter and I want them to be safe.

  • nx8

    Great stuff here. The information and the detail were just

  • I try my best to not over think a new way of doing things. In this case I think in terms of “how does amazon expose their API’s to me” so that I might make a mash-up application of their infrastructure as a service. I can hit their API in real time via HTTP calls. Or I can take the dependency on their SDK which exposes the API to me as .NET shapes. I find that taking the SDK dependency means I loose some of the granularity that their API might expose but gives me dev time productivity. In a microservices land I might make such an SDK for others to consume my service. This is great for the API that I might expose. But it seems a touch distasteful to make an SDK with my message shapes for someone to subscribe to via NServiceBus. But if the coupling is still just to the SDK…not to a flavor of the underlying infrastructure it might be ok. Said differently if the recipient of my messages is also .NET – then and SDK with my message shapes might not be horrible. If I were to change the conversation to “what if the client were written in java” then a shared nuget package with .NET stuff wouldn’t work as well. Instead I might create an HTTP bridge or something of that nature to bring java into fold.

    • jbogard

      Re: NSB – those messages on the wire are recipient agnostic. It’s just JSON/XML on the wire, they’re intentionally not meant to be tied to .NET (anymore). They used to be pretty tied to it.

      You do have the NSB headers, but that’s pretty normal to have app-centric headers in messaging, it’s done in RabbitMQ all the time.

      Or hey, you can do file-based integration instead of APIs! Honestly all integration options are on the table, none are inherently better or worse, they just have tradeoffs.