Many people are simply slapping an interface on to every web application they build and don’t give it much thought. Tim is right in asking why try to coerce your website into a REST paradigm since the browser is a bad (or rather not a general) REST client. We shouldn’t.
However, this doesn’t dispose of the need for a truly REST framework (that is one which uses real hypertext for is representations).
Lets say I have a compelling web application for which I publish a separate API. Assuming that I have a business model associated with that application, then someone is going to take my API and use it in some way I hadn’t anticipated. Now I’ve added value to my application without doing any work. That ability has a multiplicative effect as there are no limits to how many people can use my API. That applies to any API but REST is more likely to succeed since it is intended to promote long term (on the scale of decades) serendipitous evolution.
So there is value in publishing APIs for my applications (independent of the user interface), the potential for added value in the future.
What I am suggesting is that you should architect your systems so that you produce one (internal) application for each concern in your system. That is to say, if I was building an on-line storefront, I’d create three REST applications: one application to handle user management, one to handle product Management and one to handle order fulfillment. These all would be completely internal to my business.
I would then create a publicly accessible application which would consume the other three applications. This would be a User Interface so it would be designed around User Centered Design principals.
So what are the advantages to the approach? Here are but a few.
- Scalability — Let’s say that the sale of widgets has gone through the roof and I’m seeing 10,000 people every hour come to my site. I’m going to have to look at load balancing. I now need to distribute my Web UI onto 4 machines, two of which I’ve put in Ottawa, and two are here in Vancouver. What else do I need to change? Well it turns out that once you’ve logged in (session mgmnt is handled by the Web UI), all you need is the User’s profile information. Since that is seldom changed in a session, the Web UI will be able to use its cached version; so long as the user management can respond with
304 NOT MODIFIEDefficiently, one server can handle its load handily. Far more people browse than order, lets say 1 in 10 people place an order. That means that we’re expecting about 1000 orders per hour which our order application can handle nicely so we won’t scale it for now. But we are going to have to do something about the product information, that needs to scale with the Web UI… or does it? From the point of view of the Web UI, the product info is static and most of it changes infrequently. I don’t need to put up multiple instances of my product management app, I simply need a good web cache at each of my data centers to sit between the web UI and the product management system.
- Maintainability — With four independent systems making up or storefront, I can now push changes to any one without affecting the others. This has some great operational benefits as any change to a system affects the whole system so when you’re only changing small systems that reduces the risk. Its also more testable. It becomes very easy to write mock applications to consume the resources of any of your internal systems or to produce mock APIs to test your web interface (this makes it very easy to write resilient selenium tests since the data won’t change).
- Low(er) Risk Evolution — Next week the VP of Business Development is going to announce that you have a strategic partnership with Acme DooDads. They’re going to sell your widgets. Now we need to expose our product and order systems to them. We also want to make sure that only they have access to these services so we’re not going to put them outside the firewall. Instead we’re going to write a new public application that will interact with our product and order systems. Since ACME isn’t as modern as we are, we have to build a SOAP interface for them. Since they’re sending all the shipping particulars in each order request, we’ll create a new “AcmeShippingDestination” application to hold the representations that would normally be in our User management application. Here’s the value: We’ve added a significant number of features without editing any of the existing code. It also applies internally; I may need to create an application that consumes one or more other REST applications to expose other REST resources to internal applications adding some value along the way.
- Fully Aware Deputies — Maybe its because I spent 7 years developing online banking applications, but I always expect the worst. If you look at your average open source CMS (like Word Press or Radiant) you’ll notice that one application handles both the distribution and creation of your content. This is an instance of “The Confused Deputy Problem”http://en.wikipedia.org/wiki/Confused_deputy_problem. The reason is that all the database access is through one user who generally has universal read/write privileges and any attacker who can exploit flaws in the system (and they always exist) has full reign over the database. A better architectural approach is a publicly accessible application that has only the permissions it needs and a private application that has full access. With REST, I would argue that our “Read Only” product product resources that are used by the Web UI are different than the “Read/Write” product resources that our business users are going to interact with. That is if we have separate applications for both the read only and read/write resources, I avoid the confused deputy and I can use normal network access controls to keep everything safe and secure. This is especially true in companies where information is classified in security terms as “Public”, “Private”, “Confidential”, etc. There you usually have strict controls on who can see the different types of information. Further any single entity may have information that can be disclosed at each security level; it would be most appropriate to have different resources for each security level served from each from their own application (again so that network level access controls can be used).
Some of these things are not unique to REST, to be sure. It also puts a little bit of strain on certain parts of our application; because we don’t know what is at the end of a URI, or if I even have permission to access it, we have to be a lot more flexible in what we expect. Actually flexibility is one of the hardest things here. Think of a web browser (which is a model for how we develop applications that consume REST resources); all it knows is the starting URI you provide, HTTP and how to render a handful of media types. This is all that your REST client application may know as well.