New Http support for Command/Queries in Griffin Framework

I’ve just pushed a new CqsHttpListener and CqsHttpClient to Griffin.Framework. With it you can host a small HTTP server within your application to be able to receive Command/query objects from your client applications.

Invoking a command

To get started let’s just define a small command:

public class RaiseHands : Command
{
    public string Reason { get; set; }
}

The command is invoked client side by using our simple http client:

var client = new CqsHttpClient("http://localhost:1234");
await client.ExecuteAsync(new RaiseHands {Reason = "all YOUR base"});

That’s it.

Processing the command

To be able to execute the command we need to start by defining a handler:

public class RaiseHandsHandler : ICommandHandler<RaiseHands>
{
    public async Task ExecuteAsync(RaiseHands command)
    {
        //TODO: Do something useful
    }
}

Once done we also need to be able to invoke it. In Griffin.Framework we have two options. The inversion of control container support or the simple support. For this exercise let’s use the simple support:

//can be an ioc bus too.
var commandBus = new SimpleCommandBus();
commandBus.Register(Assembly.GetExecutingAssembly());

//takes care of execution
var processor = new CqsMessageProcessor {CommandBus = commandBus};

//receive through HTTP
var server = new CqsHttpListener(processor);
server.Start(new IPEndPoint(IPAddress.Loopback, 1234));

So what the server do is to translate the incoming command object (serialized as JSON), find the handler and execute it.

Using a regular HTTP client

The cool thing is that the server supports regular HTTP clients too. Just make sure that the command is represented by a valid JSON string.

Here is an example:

var client = new HttpClient();
var content = new StringContent(@"{ ""Reason"": ""So simple!"" }", 
                               Encoding.UTF8, 
                               "application/json");
content.Headers.Add("X-Cqs-Name", "RaiseHands");
await client.PutAsync("http://localhost:1234", content);

The problem with JSON is that there is no way of identifying if the supplied string is a command or which command that is for that matter. That’s why the X-Cqs-Name header is included.

At server side we also need to index all commands/queries. You can do that object by object or by scanning an assembly for all command/query objects.

var server = new CqsHttpListener(processor);

//map a single object
server.Map(typeof(GetUsers));

//map all cqs objects in the specified assembly
server.ScanAssembly(Assembly.GetExecutingAssembly());

//run
server.Start(new IPEndPoint(IPAddress.Loopback, 0));

The HTTP approach also allows you to invoke CQS objects directly from the client side using AJAX (or web sockets).

Summary

Everything works for commands, queries, request/reply and application events. I’ll push a new nuget package as soon as I’ve created more tests for the different CQS object types.

Code as github.

I’ll probably create a package for ASP.NET MVC5 too and a Griffin WebSocket host in a near future.