Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

New HTTP Support for Command/Queries in Griffin Framework

4.50/5 (2 votes)
9 Mar 2015LGPL32 min read 8K  
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:

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

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

C#
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:

C#
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:

C#
//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 does is 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:

C#
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.

C#
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.

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

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)