On Wed, 2006-04-05 at 15:37 -0700, Dr. Ernie Prabhakar wrote:
> I want to provide a web service that, say, converts HTML documents
> into various formats. The naive RPC method would seem to be to
> create a special URL string for each type, e.g.:
REST is a model for managing state mutation and transfer in a large
scale distributed architecture. People often get caught up in whether a
simple conversion activity of this kind is RESTful. They want to add new
URIs to the process and store the result somewhere on the server side.
This is not useful. The starting point for understanding a RESTful
architecture is to think about the state that needs to be retained on
the server side in order to keep things ticking along. In this case and
cases like it, there is no server-side state. Because there is no
server-side state, there are no server-side resources that need to exist
to manage or delimit that state.
The server side does not retain the converted document, so it returns
the document in the HTTP response and forgets about it. If it wanted to
keep the document around for other users of the service to view, it
should store it and represent the stored state as one or more resources.
If it wanted to keep public statistics on the number or types of
documents converted, it should store statistical state and represent the
stored state as one or more resources.
The difference between REST and RPC in the null-state case is not very
wide, especially when we are already constraining ourselves to the
document transfer problem domain. The REST version on the wire looks
>> POST /doc2pdf
>> (doc document)
<< 200 OK
<< (pdf document)
The RPC version looks like this:
>> ConvertDoc2Pdf(doc document)
<< (SUCCESS, pdf document)
This difference is still important. If we think about what the software
looks like that invokes the request, REST looks like this:
resource = getResource("http://example.com/doc2pdf")
document = resource.POST(document)
RPC looks like this:
docConverter = getDocConverter("http://example.com/doc2pdf")
document = resource.ConvertDoc2Pdf(document)
The RPC approach allows for a lot more of the variation at the code
level to be translated into variation all the way down to the network
level and back up again to the application level on the server side.
REST takes a uniform approach, and only the code that wants to handle
things in a domain-specific way has to do so. The code that gets
messages to that code and directs them back away can be generic and
REST pushes unformity of verbs and message structure at the network
level, and in fact forces us to rethink the application level
significantly. If the uniform version works, why waste time inventing a
more specific or type-safe version? Why validate the whole data
structure down in some network stack when you can transport the raw data
to where it is used and only process what is needed when it arrives? Why
insist on converting a message into an intricate structure of data when
you are just going to reencode it again for transmission or display it
to a user? Why not just retain it as strings until you know what you
will do with it?
The difference between REST and RPC is much clearer when we add
server-side state to the picture and the existence of intermediataries
between server and client. This what Fielding's work is mostly about.
However, there is a world view in REST that says "types don't work on
the network unless everyone understands them". It says that html is
interchangable, but the xml schema you dreamed up yesterday is not. It
says only parse what you need to, and ignore what you don't understand.
It says that the network with all of it's different agencies and
opposing interests is not an environment where traditional
object-orientation works. When we look at what does work, we find
ourselves thinking about compatability in different ways.
REST is not the end goal. It is not an absolute good in it's own right.
It is the benefits of REST that cause use to follow its philosophy. REST
is better than object-orientation for the same reason as we have web
browsers instead of CORBA-browsers. Uniformity is key. Simplicity at the
network level is key. Managing state transparently as resources is
important for its own reasons, but when you are looking at stateless
services such as document converters they really don't come into the
picture that much.