It's not RESTFul, but does it matter?

Quite too often we see discussion about what is and what is not REST, some developers excitedly discuss about REST purity. However, does it actually matter? Do you need that level of "purity"? I personally think that it does not and will try to explain why, although I am already convinced that will fail on my attempt.

REST means REpresentational State Transfer, and while almost everybody will tell you that is not necessarily related to HTTP (and technically isn't), in reality, it is, and that's a fact. So when we apply it to our Web Services, we have our new REST APIs or RESTful APIs mixed with HTTP flavors.

Also consider that they do not conform a protocol, or a specification, is an architectural style. So, technically, they are a set of conventions and guidelines and not an actual set of unbreakable rules (like a protocol).  

But they are great, RESTful, REST-like, almost RESTful APIs are all great. I have been writing and playing with APIs since around 2001, and came all the way from XML and SOAP (from the manual aspx, to asmx, to WCF) and then into JSON and REST , and I love them all. In fact, the only thing I don't like about REST is the people behind it trying to defend it so vehemently  :) But there are some issues I am sure you might have encountered before:
  1. Authentication: Purity zealots say that REST is pure and not HTTP-only, yet they use HTTP headers/cookies for authentication over a RESTful API.. wat?
  2. Sometimes it becomes really hard to do it the REST-style (and RPC-style feels natural) 
  3. The typical verbs are not expressive enough for my API (all real life systems are more complex than CRUDy examples) and this kind of ties to #2.

Rule of thumb: Never stop when they tell you   "it's not RESTful if..."

I found this online, no idea who the author is...

Lets shed some light over these 3 cases: 

Case #1

Authentication against a RESTful service: there should be no discussion, your system architecture will make things easier or harder for you, and your decision can't be to put the "purity" of an architectural style over the consistency, completeness and correctness of your system. I have seen scenarios where cookies bring transparency, and others where a token over query string parameters are a better fit. Don't stop a solution because someone tells you "it's not RESTful if...".  

Case #2  

REST is definitely good, but it is not enough, because not everything is a resource. While the idea of exposing documents, files, resources (nouns) feels natural for a huge amount of cases, you will eventually find a situation where is not natural to expose something as a resource. "Resources" and "Processes" can be really complicated in the enterprise. Think about it, we are translating the logic from our object and methods/functions, to basically one "object", whose status can just be CRUDily accessed. 

The REST-workaround to deal with this kind of issue is to "make it" a resource and then deal with its status. Let's say I have a process that can start/stop/pause/rotate/jump/recharge/sing (is my process, so the actions are whatever I decide :) ). One RESTful way to do this is to expose:

GET http://address/process/status 

as a resource. We could GET the endpoint to query and then perform PUT  with the new status every time:

{
   started:true,
   paused:false,
   charging:false
   //other fields
}
and then starting, or recharging would imply sending the status over via a POST.

POST http://address/process/status

This does not feel natural, passing back and forth the whole status of a process to start/stop "actions". It might be a RESTy way to do things, but certainly it does not help me on this case. What if we have 100 actions? RPC would be a better option here.

POST http://address/process/<start|stop|pause>

We can do things like:

POST http://address/process/jump?howhigh=20

and we could still query the status by calling in a RESTy way:

GET http://address/process/status

There is no rule against combining them. Just go over you API and improve things as you go. Make things easier for you and the clients of your API. Blindly following guidelines for the sake of it, will yield no reward except suffering. 

Having a well documented API is more important than breaking your head trying to conform to some guidelines.

Case #3

The verbs are not enough. Lets take the data structure of a stack and try to represent it in a REST API:

http://address/stack

would be my "stack" resource. The only way to modify a stack is by calling PUSH and POP operations, we don't have those verbs, but we can try and see if they fit our RESTful idea. I also need a COUNT, to know how many items are on the stack, and a PEEK, to read the one on the top without modifying the collection. Care to make this in a restful way?

GET http://address/stack

What should this do? To be RESTful, this should just return the whole stack, which is not very useful for what you typically want a stack (could apply same logic to a "queue"). And would be a terrible way to get the COUNT, and I really want the O(1)  order of some operations over a stack.  

POST http://address/stack

This could be our PUSH, sending an object to the top of the stack. What about POP?

DELETE http://address/stack

This makes no sense, because we are not deleting the stack itself. Then even something like /stack/top, would also be incorrect, since the element at that URI would be different after a delete, and finally because DELETE must be idempotent. 

Then what? POST? We already used it. Once you reach this point, is better if we just go back RPC again.

GET http://address/stack/count  (COUNT)
GET http://address/stack/top    (PEEK)
POST http://address/stack/push  (PUSH)
POST http://address/stack/pop   (POP)

POP would "modify" the stack, so, a POST is the catch-all verb to use here. DELETE wont do it and PUT even less, they are both idempotent. 

All these can be also applied to a queue, a circular queue or many other data structures. The verbs might not be enough to support your operations from a semantic point of view, and URIs might not be unequivocally representing a resource. /stack/top, its not a permanent URI for "the element" on the top, is the address of the "top of the stack", the element itself can and will vary over time.

I have a hard time trying to understand how RESTful could be a silver bullet without the ability to represent the most simple of structures. REST and CRUD-style is not enough for everything out there.

Comments

Popular posts from this blog

Get-ChildItem vs Dir in PowerShell

The case for a 4 week sprint

NODE.js fs.readFile and the BOM marker