NServiceBus, Messaging and RESTful Endpoints

I write a lot of throw away console apps when performing system integration, especially ones that send messages on the bus to isolate sub processes for testing. This sometimes evolves into handy testing harnesses, but most of the time it just gets overwritten with new tests and later ditched.

In the past I’ve written generic http endpoints that accept commands and put them on the bus for you. I’d then use something like PostMan to post json messages to it. This is good, but you lose the help from intellisense when constructing commands, and frankly constructing these messages into JSON is a real pain.

The next step for a generic http endpoint like this is to make it more RESTful. Make it discoverable using links, after all, if it doesn’t have hyperlinks.. it’s not REST.

The idea is to have the API allow you to navigate endpoints and it’s messages as resources. In this sense the state of the endpoint might be the contracts it exposes. The API will describe the contracts and allow you to create instances of them which are put on to the bus.

To achieve this, we need to build up a list of endpoints and the contracts.. something like this

        new Endpoints()
            .ForEndpoint("Billing")
                .LookIn(typeof(Billing).Assembly)
                .For(t => IsContract(t))                       

            .ForEndpoint("Sales")
                .LookIn(typeof(Sales).Assembly)
                .For(t => IsContract(t))

            .ForEndpoint("Clients")
                .LookIn(typeof(Clients).Assembly)
                .For(t => IsContracts(t)                       
             )
        ));

This will be used by the EndpointsController to then build up a view of all the endpoints and their contracts in a RESTFul manner.

    public class EndpointController : ApiController
    {
        private readonly Endpoints endpoints;

        public EndpointController(Endpoints endpoints)
        {
            this.endpoints = endpoints;
        }

        public HttpResponseMessage Get()
        {
            return Request.CreateResponse(endpoints.AllEndpoints());
        }

        public HttpResponseMessage Get(string endpointName)
        {
            return Request.CreateResponse(endpoints.ContractsIn(endpointName));
        }

        public HttpResponseMessage Get(string endpointName, string contractName)
        {
            return Request.CreateResponse(endpoints.FindContract(endpointName, contractName));
        }

        public HttpResponseMessage Post(string endpointName, string contractName, FormDataCollection formData)
        {
            var descriptor = endpoints.FindContract(endpointName, contractName);
            var contract = Activator.CreateInstance(descriptor.Type);            

            foreach (var property in descriptor.Type.GetProperties())
            {
                var propertyValue = formData[property.Name];     

                object value = null;
                if (propertyValue.TryConvert(property.PropertyType, out value))
                {
                    property.SetValue(contract, value);
                }
                else
                {
                    descriptor.ResponseMessage = string.Format("Value for '{0}' provided was in an incorrect format.", property.Name);
                    return Request.CreateResponse(System.Net.HttpStatusCode.BadRequest, descriptor);
                }
            }

            return Request.CreateResponse(descriptor);
        }
    }

From this we can navigate the API through each endpoint, easily identify which contracts belong to which endpoint and build a form to post them to the API.

Kudo’s must be given here to Howard Dierking for RestBugs. This is a great example of a Restful API, using a RazorMediaTypeFormatter to respresnt resources as html.

Using a html representation will allows us to interact with the API in a browser, just like you might with a typical website. Ironically, your endpoints begin to look a lot like asmx services when navigating to them in the browser. As a note, building REST APIs like this, i.e. that are browsable, is a very powerful tool for making sure clients can easily navigate the API by following links. (For a great series on REST have a look at Ploeh’s thoughts on the topic.)

Let’s have a look, the root of the API lists out all the endpoints:

API Root displays all endoints

Selecting an endpoint will list out all the contracts for that endpoint..

Selecting endpoint displays its contracts

Clicking on a contract will present a form, allowing you to post a command to the endpoint.

API returns form for posting a contract.

Simples.

The source for this is up on Git here. At the moment it’s really just a proof of concept and doesn’t actually post messages on any bus, my thoughts on this are to try to keep it agnostic to any kind of messaging infrastructure. I use NServiceBus in my day job, but it really could be used for anything. Most likely I’ll allow the “Endpoints” class to capture actions for bus.Send / bus.Publish depending on whether a message is a command or an event.

Feel free to fork what’s up there now and get it working with your messaging tooling!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s