User Tools

Site Tools


csharp:aspnet:webapi

ASP.NET Web API

ASP.NET Web API is the applications remote facade. It can be used in process, for example by an ASP.NET MVC application running in the same domain, exposing views to browsers, or it can be used remotely, for example by an httpClient inside a Windows Forms application or from inside the browser via AJAX calls.

Applying CQRS principles, the application itself will be split into a command and a query side. This will be reflected directly inside the Web API. There will be query controllers, as well as command controllers.

The remote facade of my choice thus far was WCF. Everything that I need to be done inside WCF1) can be done inside the Web API:

Message Security

With WCF there are plenty of options for message security2). However, that plethora of options also makes life very complicated. In Web API, if you want message security, you use SSL. That's it. Simple, common, standard, easy to use because every platform has components to handle SSL.

Object Formatting

WCF uses XML, and can be configured to use JSON as well. Web API uses XML or JSON as well, and respects the content-type header of the request3).

WCF requires the [Serializable] attribute or the [DataContract] attribute together with [DataMember] attributes on each property. That gives you full control over serialization, but again, it unnecessarily makes things more complicated than they must.

Web API can deal with POCOs. That's that, nothing more needed to be said.

Polymorphism

WCF requires [KnownType] attributes. Web API uses the Json serializer. The WebApiConfig can be tweaked unter the App_Start folder to deal with polymorphism by including the type name for either everything, or just for objects. Simply set the json.SerializerSettings.TypeNameHandling property for the serializer:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            ...
            ...
 
            // New code:
            var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
            json.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
 
            config.Formatters.Remove(config.Formatters.XmlFormatter);
            ...
            ...
 
        }
    }

Now, the JSON Objects supplied by the Web API will include a $type attribute for every object passed out. Also, when deserializing JSON back into the model, the $type attribute will be used to deserialize into the correct type.

This is especially useful for an aggregate command handler, which handles all commands sent to it for a certain aggregate. The commands can be of different types and the list of possible types is extensible. So all the client has to do is to include the Type, eg. { $type: “ProM.RescheduleServiceAction, ProM”, id: … } and send the command off to the command handler for all commands.

The same effect can be obtained by having separate handlers for different commands. However, I4) believe in batching commands, and guaranteeing to the user that either all will pass or fail. And when sticking to SQL Server 2008 or higher, no distributed transactions are needed for this, even if the commands go to different databases inside the same datebase server.

Without batching, you will either have to build composite commands or workflow engines. The problem with composite commands is that the same smaller command can now be part of more than one command, and system maintenance will suffer. The problem with workflow engines5) is that they are complicated, and should not have to be used in simple cases where a user wants to change a name and the bithday together, and if one of those fails, having to implement a complicated workflow to compensate for that. A simple transaction handling two separate commands is so much easier6).

1) which was my first choice for the remote facade, but which will not be replaced by the Web API with certainty
2) Message and/or Transport
3) if configured to do so
4) not everyone, especially not the people rejecting distributed transactions
5) or SAGAs
6) KISS, n'est ce pas?
csharp/aspnet/webapi.txt · Last modified: 2013/06/23 14:54 by rtavassoli