Tuesday, May 13, 2008

Microsoft Facilitates White Box Services

Microsoft has just recently announced the upcoming release of .NET Framework 3.5 Service Pack 1. This service pack includes a couple of changes to the WCF DataContract serialiser.

The first is attribute-free DataContract serialisation, where it seems we no longer need to place DataContract/DataMember attributes on every serialisable member anymore. They are referring to this as POCO (plain old CLR object) serialisation.

The second is interoperable object references. The DataContract serialiser now supports serialisation of object graphs rather than just trees. This was previously possible in WCF, but the PreserveObjectReferences setting needed to be enabled when creating the DataContract serialiser.

The issue however was that before this service pack, object references were not serialised in a way that was interoperable with other Web service stacks. Now WCF supports an interoperable object reference scheme that allows it to serialise object graphs. This in theory allows us to serialise object graphs that contain circular references in an interoperable way.

According to Microsoft, the big advance here is that now Entity Framework types are serialisable via the DataContract serialiser.

Now all of this new found power may sound really good. But personally, I find this all rather disturbing. Microsoft is effectively empowering developers to directly serialise their domain models.

If we no longer need to decorate classes with DataContract/DataMember attributes, then our domain classes become immediately eligible for serialisation.

But hang on, what about all those object references in my domain model that caused me serialisation grief in the past? And what about those references to the Entity Framework classes in my domain model (which shouldn't be there, but Microsoft made me put there)?

Well, Microsoft has solved that problem with the new found power of the new DataContract serialiser. You're all ready to go and expose your domain model directly in your service contract!

But hang on, that's really bad practice isn't it? Absolutely! If we expose our domain model in our service contract then we have a white box service. We couple our service consumers to our service implementation.

Moreover, domain models have considerably different design constraints to message schemas. Domain models are optimised to represent business logic, whereas message schemas are optimised for representing documents transferred over the wire.

You want to be able to design your domain model to most accurately reflect the problem domain, without having to worry yourself with how efficiently it might be serialised over the wire.

Generally, you will tend to find you want to serialise different aspects of your domain model depending on the message being sent. If you directly serialise your domain objects, you won't have that flexibility to choose different data to be serialised for each message.

So for a number of reasons we don't ever want to directly expose domain objects as part of our service contracts.

Now it seems that Microsoft has added these capabilities to the DataContract serialiser to support the new ADO.NET Data Services framework released as part of this service pack. This technology is intended for supporting RESTful architectures.

In order for this new technology to work, Microsoft needs to directly serialise its entity classes over the wire. Now I'm not bagging REST here (because that will start a flame war), but I disagree with Microsoft's implementation here because again, we have our entity model that we use to represent business logic leaking outside our service boundary. Thus, we have coupling between our RESTful service implementation and the service consumers.

Moreover by making this change to the framework, Microsoft has made it considerably easier for SOA developers to directly expose their domain models as part of their service contracts - and I assure you, the easier the framework makes it to do the wrong thing, the more developers will do it.


Unknown said...

I'd like to see an alternative REST framework. Perhaps you're up for starting an open source project to do it the right way, Bill? I'll contribute.

Bill said...

Hi Nathan,

I must say I don't use REST myself, so I wouldn't be the right guy to contribute to such a project.

I'll be doing a post comparing and contrasting SOA and REST at some point in the near future which I'm sure will attract a lot of debate. :)


Lee Campbell said...

This all just reminds me of developers passing Datasets over the wire. To be fair to Microsoft they are just providing the technology, the abuse of it is up to us. What would be nice is if M$ released some white papers that explained the dangers of abusing the technologies available, and provide some direction for a better way.

Bill said...

Hi Lee,

I agree that it takes two to tango. It is us at the end of the day that abuses the technology as you point out. But why provide a capability in the framework to do the wrong thing? What value does that add?

In my experience if the technology can be abused, it often will be. It is just too tempting for developers to directly expose their domain models in their service contracts as it means they don't need to explicitly design messages and write message/domain mapping logic.

At the end of the day, developers usually take short cuts where they can in the interests of getting the immediate problem solved as quickly as possible, without thought or consideration for the long term problems such a strategy will cause.

An example where Microsoft is trying to do the right thing is the ASP.NET MVC framework. Here, the framework makes it very difficult for developers to violate the separation of concerns between model, view and controller.

As a result, we will get considerably better quality systems built on this framework as opposed to classic ASP.NET.