Sunny Ahuwanya's Blog

Mostly notes on .NET and C#

Introducing RestBus

Have you ever tried to use RabbitMQ in .NET and found the experience less than satisfying?

I was in that position about two years ago. I was working on the design for CSharp Pad, which has two main components: a web application that takes requests from users and a back-end server that is forwarded those requests to process.

The initial design was to have the web application talk to the back-end server using HTTP calls.  At some point, I realized that won’t work properly because of HTTP’s Head of line blocking problem (now resolved in HTTP/2).

Since HTTP/1 is a synchronous protocol, users issuing long running queries could block other users’ queries, even though the server has the capacity to process the blocked queries simultaneously with the long running ones.

The solution was to send messages to the back-end server asynchronously. One way to do that is to use a message broker. This also provides other benefits such as the ability to easily scale the server horizontally.

Enter RabbitMQ

I went with RabbitMQ as my choice of message broker, based on its popularity and relative familiarity, having worked with it in the past.

Now, I had a new problem: I already have functioning web service endpoints (in ServiceStack) for my server. I’ll either have to rip them out or make them work with a RabbitMQ friendly messaging framework.
I looked at a few messaging frameworks, MassTransit in particular, but found the frameworks and accompanying documentation a bit daunting.

Why can’t the framework message the endpoints directly?
Why can’t sending messages through RabbitMQ be as simple as a HTTP call?
Why do I have to import a new framework instead of a lightweight library?

There didn’t seem to be an existing library that met my needs satisfactorily, so in a bid to become a better lazy programmer, I decided to write one.

Fortunately, ServiceStack has a message queueing interface, so it wasn’t too difficult to get it to listen for requests from RabbitMQ and send responses to a designated queue, using the RPC messaging pattern
A nice feature is that the library’s client inherits from the same base class as HttpClient and behaves just like HttpClient, so sending messages is as easy as making HTTP calls.
The more I played with the library I had written, the more I realized that this was an extremely easy way to use RabbitMQ, so I open sourced it.

RestBus Is Born

Around that period (early to mid 2013), ASP.NET Web API framework was gaining a lot of popularity. On a whim, I tried to get Web API to work with RestBus and succeeded. The coding effort was surprisingly a lot less than the effort I put into ServiceStack.

After that, I got side-tracked by other things and didn’t pay much attention to the project. Occasionally, I’d get an email inquiring about a RestBus related issue.

A couple months ago, I went to the Github project page and noticed there were about fifteen stars, five forks and three issues.
Wow! That’s impressive for an alpha-quality, poorly documented, unmaintained repo. People are finding this library useful!

So I started working on RestBus again. This time with a focus on getting ASP.NET Core (formerly known as ASP.NET 5) support, and to improve the overall design of the library.

Today, I’m pleased to announce stable releases of RestBus with ASP.NET Core, Web API and ServiceStack support.
RestBus also happens to be one of the fastest RabbitMQ .NET libraries available.

Interestingly, a few weeks ago, I ran across a 2007 ACM Queue article “Toward a Commodity Enterprise Middleware”, written by no one other than John O’Hara, the originator of the Advanced Message Queuing Protocol(AMQP) where he describes on a broader level, what I was trying to achieve with RestBus:

"Web services has four basic parts: service description, XML message content, service discovery, and transport. The transport is commonly presumed to be HTTP, but it does not have to be. Enterprises often use XML over messaging middleware as the transport for all the benefits that brings. Having done this, enterprises find they have created the problem they wanted to avoid: running an open architecture over a proprietary transport. Combining Web services with AMQP as a transport gives the richness an enterprise needs with the openness it craves in its core architecture."

Looks like I unwittingly stumbled upon a messaging architectural style envisioned almost a decade ago.

What’s Next?

RestBus is at a point where its public interfaces are finalized, so future updates will not break (or break with minimal impact) on dependent applications.
It is beta software but is safe to use in production. CSharp Pad has been running RestBus for almost two years without any issues.

I’ll keep working on the project. There’s a lot left to be done including support for Azure Service Bus and Nancy framework (which I’m excited about) .

Check out RestBus and let me know your thoughts. Contributions are welcome.