REST over MQTT for Constrained Devices/Mobiles
MQTT the IoT Buzzword
If you run your fingers across google you will find some really good articles about MQTT. Yet, here is a blog post to all the handy links about MQTT. In fact I covered MQTT a great deal in my previous post in the Pub/Sub context. So basically I am assuming some MQTT background if you reading this, so I suggest you read the above links before proceeding.
If you are already having a grasp in MQTT you would already be knowing that the classical uses case for MQTT is — “Sensors/Constraint devices posting their events in real time”, i.e. asynchronous posting to server. But thats not the only place where MQTT is gaining ground. In the mobile context MQTT is positioned for x-platform Mobile push notifications and Facebook started using MQTT for their messenger app. I wrote my observations about Facebook’s choice of MQTT over APNS/GCM here.
Synchronous Req/Res pattern and MQTT
In this post I wanted to focus on how constrained devices/mobile phones can make REST calls (Request/Response) over MQTT. Let me clarify that a bit , I am not going to talk about how to go about using MQTT in a Req/Res scenario like making an REST API call from Mobile, wait for a response and use it in the Mobile UI. Because there are lot of quality material out there talking about this exact topic. I found one here. I am not suggesting or advising that REST over MQTT is the way to go for constrained devices/Mobiles to make REST API calls, because CoAP is designed to provide REST for constrained devices. ws4d — web service for devices project using CoAP, check this out — but if you choose to go with REST over MQTT here is one way to do it ;-)
Well what am I going to talk about here ? Using some of the great advices in the above post we could write neat Req/Res patterns using MQTT. But what if you a Mobile app already in store making money powered by HTTP/HTTP(s) driven Mobile APIs ?
We need a way to effectively leverage our existing APIs and just have HTTP/HTTP(s) replaced with MQTT
Lets define success and work backwards on how to achieve it.
How does a typical HTTP to MQTT conversion project would look like?
- The Mobile App will have a new MQTT/Topic based communication layer added.
- All existing HTTP or Req/Res calls are carefully replaced with Topic based MQTT publishes.
- A new Server side facade is added to act as a bridge between MQTT calls incoming and existing API layer. This layer facade will receive MQTT requests , translate it into API aware input and call the respective API, get the response back from API, send it back to Mobile as MQTT response.
Sounds promising and a bit of a stretch ? hang on with my train of thought for few more minutes — you will know ;-). How to design your topic structure to suit Req/Res pattern and how to make your Mobile do MQTT is covered in the posts sited above. Say you have done that how does the Server side of thing going to look like — lets talk about that with a use case.
LoginAPI use case
Your mobile App is doing a HTTP call to the existing login API, how can we apply the above steps to achieve MQTTtize our calls. I am going to introduce a special kind of MQTTSubscriber which will do us the job called APIRequestRouter. Following can be assumed as a UI from which you can configure new APIRequestRouters as you wish. Below is a mock UI to show a feel of how you might be setting up routers. Lets stick to login use case — take a look at the first entry in the table. All it says is the MQTTBroker is having a listener in this case a Router with RouterID “Router1”, the listener listens to a topic “/login/request/*”, it is linked to an API in URI “http://api.abc.com/v1/login", with a data formatter to confer the raw MQTT request to JSON before calling the API.
The Data formatter can be instantiated in the runtime — think of reflection or Dependency Injection. Note the MQTT topic is supports wild card so login requests from any client will reach Router1. The Mobile would actually use the topic with its client id — something like /login/request/Client1 or /login/request/Client2. Having a console developed like this useful to control in the runtime. You could design the base Router code multithreaded to make it high performant.
Get the idea ?
How to configure a APIRequestRouter
LoginAPI call flow
This is how the flow looks like.