Udi Dahan
quotes an email
I sent him some time ago when I was trying to get to grips with the fundamentals
of SOA in contrast to the fundamentals of REST. He refers to it in a
corresponding blog entry:
Astoria, SDO, and irrelevance
I concur that adding a REST-like front end to a database isn't a particularly
useful thing to do. HTTP is not SQL. It doesn't have transactions. Attempts
to add them are unRESTful by the definition of REST's statelessness constraint,
or at least to be approached with caution. Udi says that getting data
out the REST way is fine... but updating it using a PUT requires a higher level
of abstraction. Where I differ from Udi is that he says a higher level of
abstraction is required than PUT. I suggest that a PUT to a resource
that is pitched at a higher level of abstraction is what is usually required.
Let's take an example. You have a database with a couple of tables. Because
we are in a purely relational environment, our customer information is split
across these tables. We might have several addresses for each customer, lists
of items the customer has bought recently, etc.
Exposing any one row or even a collection of rows from any one of these
tables as a single resource is frought with problems. You might need to GET
several aspects of the customer's data set
in order to form a complete picture, and the GETs could occur across
transaction boundaries. You will very likely one day end up with a data set
that is inconsistent.
PUT requests to such a low-level object also run us into problems. Any update
that requires multiple PUT requests to be successful runs the risk of leaving
the database in a temporarily- or permanently- inconsistent state.
The answer here is to raise the level of abstraction. We could introduce
transactions to our processing, but this increases complexity and reduces
scalability. While it may be the right approach in many situations, it is
usually better in client/server environments to expose a simplified API to
clients. We don't really want them to know too much about our internal database
structure, so we give them a higher-level abstraction to work with.
In this case the starting point would likely be the creation of a customer
object or customer resource. In the SOA world where methods and parameter lists
are unconstrained, we might have a getTheDataIWantForThisCustomer method and
corresponding updateThisDataIHaveForThisCustomer method. In REST, you would do
pretty much the same thing. Except in REST, the methods would be GET and PUT
to a https://example.com/thecustomer URL of a widely-understood content type.
So which is better? I would suggest that the REST approach is usually the
best one. It can take a little time and research to come up with or to adopt
the right content type, but you will be set up for the long-term evolution of
your architecture. In the SOA world you'll need to change your baseclass
eventually, leading to a proliferation of methods and parameter lists. In the
constrained REST world we use well-understood mechanisms for evolving the
set of methods, urls, and content types independently.
In the end, REST is very much like SOA. Whatever you are about to do in your
SOA you can usually do the same thing with REST's standard messaging rather
than by inventing new ad hoc messages for your architecture. Your REST
architecture will evolve and perform better, and require less code to be
written or generated on both the client and server sides of your interface.
For me, the fundamental constraint of REST is to work towards uniform messaging
by decoupling the method, data, and address parts of each message. Most other
constraints of REST (such as statelessness) are good guidelines that any
architect should instinctively apply wherever they are appropriate, and
nowhere else.
While we are not using the same terms and are not applying technology in
the same way, I don't think that Udi and I are thinking all that differently.
Benjamin