I am designing a system which fits quite nicely into a RESTful architecture. Users can navigate a resource hierarchy from a root node, each resource links to other resources, resources have URIs etc. In many ways this is very similar to 99% of the CRUD web applications out there.
Where things get a bit different is that I want to integrate a Pub/Sub model into this architecture. So when a resource is modified I want the architecture to support updates being pushed out the relevant subscribers.
Many of my questions relate to how Pub/Sub 'topics' relate to RESTful 'URIs'. Really I want to just use the URI as the topic. I feel like in many scenarios that makes perfect sense – but I have a niggle of doubt about this and can't find any architectures in the wild doing this.
Where it gets strange is is that some URIs are queries do not fit easily into this model. It's way too complex to support pub/sub dynamic queries and I have no intention or need, but the fact this concept is widely implemented in RESTful systems makes it feel like there is a mismatch or limitation on using URIs in as topics in pub/sub system.
My resolution at the moment is that 'canonical' URIs (i.e. those that refer to a single resource at a canonical location) are fine, or even a good thing, to use as a topic. But my confidence is low due to not seeing other people doing this.
Any thoughts appreciated.
Best Answer
Mapping URIs (from REST resources) to topics, depending on what your are modeling, could result in a perfect mapping.
Through a simple example, i will try to give you some hint about how to perform this mapping. I would take as an example, two APIS: a REST API (resources) and MQTT API (topics).
By the way, MQTT is a pub/sub protocol for the Internet of Things and M2M: there are some topics located in a MQTT broker where clients can publish (
PUB topic1/topic2/...
) or subscribe (SUB topic1/topic2/...
) .Hint 1: A resource representation is a message
The idea is to map your resource URI with a corresponding topic name. So the resource representation from a resource URI corresponds to a message in a topic.
Imagine you have a resource name
/people/:id
, you will have a corresponding topic name/people/:id
.So when a client make a
PUT /people/1 { "loveBeer":true }
, clients that have subscribe to this topic (through aSUB /people/1
) will receive a notification. Notice thatPATCH
could be use also. Same apply in the opposite, if a client post a message in the topicPUB /people/1 "loveBeer":true
, the corresponding resource will be update.You would end up with this kind of architecture (picture is taken from this blog) :
Hint 2: Resources creations are also messages
From the previous example, you could think...
You will create a new resource and a message will be published in the corresponding topic (
/people
)For example, if a client performs
POST /people { "name":"schneider", loveBeer:true}
. Clients that have performedSUB /people
will receive the notificationSo you could think again and say:
Imagine a client make
PUB /people {"name":"Ailurus", "loveBeer":true}
, when message is receive, a new resource/people/42
is created and the clients have subscribed to/people
are notified.Bonus hint: Consider meta-data
That's not really a hint, since it's not really related to a mapping between resource URI/topic :)
From this blog, meta-data could be added in the payload of the messages published (but not in your resource representation).
Mainly because MQTT Client that subscribe to a topic don't know if a resource is updated or created, whereas a REST client know this information (when a resource is created, through the location header) So consider to add a metadata such as
"event": "created"
or `"event": "modified"You could even think about when a resource is created, in addition to put
{"event": "created"}
in the payload, to give the resource URI/topic name, such as{"event": "created", "location": "people/42"}