08 July 2015

Messaging with REST

One of the interesting bits of guidance you commonly get for REST services is the use of HTTP verbs to represent the user's intent. For instance, the URI "/customers/1" represents the customer with ID 1. Then HTTP verbs would map to CRUD actions. POST for Create (possibly on "/customers" without the ID), GET for Read, PUT for Update, and DELETE for Delete. So HTTP methods against that location would perform the appropriate action.

Exercise: Try naming your use cases using any nouns, adjectives, etc... but only use verbs that are valid HTTP methods.

But this is a very data-centric approach. What happens when you want to "undelete"? Or "merge" two items? Or deactivate all accounts with no activity for a year? Custom HTTP verbs aren't well supported. And the Uniform Interface principle doesn't want you making custom verbs anyway, because external clients and commodity software don't know how to use your custom verbs (does UNDELETE allow data to be sent like POST? or is it more like DELETE?). All that to say that HTTP verbs are not sufficient to express use cases, so URIs must often do that.

One way to still fit messaging into REST constraints is to look at the messages themselves as the resources, each with their own URI, rather than the aggregates (or whatever modeling paradigm you use) being resources. Likely, the only thing you want to do is create new messages for the server to process. Conveniently, this maps to a common/well-supported HTTP verb: POST. You can process it while the client waits or return a location header with a URL that the client can use the check on the status of a message. I suppose if you needed, you could incorporate other verbs for changing (PUT) or cancelling (DELETE) an in-flight message. Then you are back to a more standard REST definition. However, most systems don't care as much about managing their messages as they do about getting work done (by processing the messages as fast as possible). For my current project, the latter features are completely unnecessary so far.

If not trying to couch messaging-over-HTTP in terms of the REST buzzword, I think I prefer to look at the URI not as a resource, but as the address (aka route) of the handler for this particular message.

No comments: