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)
{
}
}
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:
var commandBus = new SimpleCommandBus();
commandBus.Register(Assembly.GetExecutingAssembly());
var processor = new CqsMessageProcessor {CommandBus = commandBus};
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:
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);
server.Map(typeof(GetUsers));
server.ScanAssembly(Assembly.GetExecutingAssembly());
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.