A non-RESTful experiment


As part of an ongoing effort to modernize the look and feel of the CSE web, we have begun to re-implement many of our internal tools in a more “Web 2.0-y” manner. The front-end tool we’ve chosen is ExtJS, a javascript framework that lets you create beautiful AJAX forms that communicate with your datastore using webservices.

The link between ExtJS and your backend data is handled via ExtJS Stores, Readers, and Writers. Stores are configured with the URLs of your webservice. One of the more interesting configuration options for these stores is restful, a boolean which tells the proxy whether to behave in a RESTful manner or using its own POST based CRUD operations. The default for restful is false.

The “Times Away” tool is an internal utility that CSE uses to allow faculty and staff to enter planned absences and which permits the display of a weekly calendar showing people who will be away from the department. We have using RESTful webservices for internal data exchange for some time, but when I recently re-implemented the Times Away tool, and I chose to write the backend in the non-restful way in order to see what insight I might gain.

Mechanics

The default data exchange scheme for ExtJS is quite simple. All interactions with the backend use POST (though this can be reconfigured to GET). Each POST contains an action parameter which can be any of the four well-known create, read, update, or destroy operations. Other POST parameters can be supplied as needed, enabling us to do typical things, like read all records for a given person.

ExtJS supplies subclasses for Json and XML readers and writers, both reasonable formats that are easily handled when writing your back end. Data from a webservice can be bound to forms and grids, and can also be read directly from the store should you desire such access. You need to make a few concessions in the format of your data (more on this below) but none of them is unreasonable.

Advantages of the Plain CRUD Webservice

  • Data are more tightly coupled to a traditional database architecture. You’re free to convert this to a disadvantage if you like. But in my mind, this is an application fed from a rectangular database table, and thinking in CRUD terms still feels the most natural.
  • Querying data is more natural. Asking a RESTful webservice for a subset of a resource is often accomplished using a query string. This can seem awkward and a violation of the purity of the RESTful esthetic. Knowing that all times away for boren might be at:
    http://my.server.com/times_away/boren

    is well and good, but finding his vacation days for the month of April might look like:

    http://my.server.com/times_away/boren?type=vacation&month=4

    On the other hand, supplying parameters specifying the desired user, type, and month, along with an action=read, seems perfectly self-consitent and in line with the way programmers commonly think.

  • Side-steps the POST/PUT problem. It has always bothered me that PUT is not widely supported by our HTTP infrastructure, leading to the need to overload the POST operation to support it.

Disdvantages of the Plain CRUD Webservice

  • Resources are not really addressable. For this limited application, this is not really a disadvantage, but it’s not going to scale well either. Web caches and search engines will respond well to http://my.server.com/times_away/boren, but not to http://my.server.com/times_away?user=boren.
  • Resources not easily browsable. One of the best parts of developing a
    RESTful webservice (or developing against one) is simply being able to type its address into your browser and have a look at it. With the CRUD webservice you’ll need to either write yourself a simple form or use some other tool.
  • Data format must be customized. For most imaginable uses, your payload needs to be formatted so that error conditions are communicated to the client. For an ExtJS application, reading boren’s vacation might return:

    {
    success: true,
    rows: [...]
    }

    or


    {
    success: false,
    message: "User not found"
    }

    While this format can easily be re-used in other ExtJS applications, it is not
    as universally portable and re-usable as a purely RESTful payload would be.

  • Error handling is fragmented. For the error condition, there is a discontinuity between an HTTP 404 meaning the service itself could not be found, and a returned success=false along with an application specific error code or description explaining the problem.

Conclusions

For an application of this limited scope, the CRUD webservice approach is fine. It offers many of the same advantages of a RESTful webservice: it uses HTTP for transport, decouples read/write operations from your datastore, and handles data in an easily human-readable format. Writing this webservice to be RESTful would have been a tiny bit more work on the back-end but not enough to matter. And the advantages of scalability, use of widely-accepted standards for communicating success and error conditions, and the ease of universal re-use outway the small extra effort.

Although I started this project with a fairly open mind, I half expected to
prefer the CRUD/POST by the end of the project, believing that it would be simpler to implement and understand. Instead, I ended up reinforcing many of the advantages of REST in my own mind. The next webservice I write will definitely be RESTful.

Comments are closed.