Saturday, April 28, 2007

Do we need frameworks for REST?

Many REST frameworks such as Restlets and simple web are gaining popularity of late. There's also a new JSR to give Java developers a new API to build RESTful web services. It's quite natural that as more people "get" REST they look for ways to simplify building their next REST web application / service.

And while I admittedly have to yet fully "get" REST, whatever I have got so far is certainly not by using frameworks that let me implement REST by writing POJOs but rather by extensive use of the POW (Plain Old Web) and POGS (Plain Old Google Search). And applying the principles I learned by using POS (Plain Old Servlets).

This is not a criticism of these frameworks. May be I still haven't understood the role of these frameworks. And may be once I do understand their goodness I myself will start using them.

But my question is this - why are servlets not good enough? Sure they have their limitations. But rather than have yet another framework or a brand new API, why not have a JSR to fix the servlets and JSPs themselves? (A good start would be to not enable sessions for JSPs by default.) After all isn't it the convenience of using frameworks galore that has kept the larger community from understanding the goodness of HTTP? Isn't it the same convenience that has made it a common practice to use (bloated) sessions?

You have to wet your feet to tread the waters. You have to get your hands dirty in HTTP to implement REST.

Thursday, April 19, 2007

Legacy operations vs. REST resources

Stefan Tilkov and Sean Gillies respond to my previous post about modelling operations in REST. There's also an interesting discussion on this on the rest-discuss yahoo group.

First of all, I think my example wasn't a good one. While the operations I had in mind were operations alright, they weren't state changing ones. I realize that my example definitely implies changing state. And I myself would advocate a PUT or at worst a POST in that case. The case I am making is for operations that don't change state but are like queries on a given resource.

I agree with both Stefan and Sean. "Resources, not Objects" as Sean puts it. In the REST world, a person does not walk but s/he reaches a location. And if I were designing a REST API for a new system I would most certainly use that approach.

But if I have existing APIs or SOAP web services such that the verbs talk and walk were firmly instilled in the verbiage of my user community, it might be a difficult proposition for me to suddenly introduce a new vocabulary for the same set of operations to my users. The user community sees them as operations and not in terms of the resulting resources (words and location). Legacy wins over technical correctness.

Tuesday, April 17, 2007

RESTful URLs for non-CRUD operations

A common way of designing a REST system is to recognize the resources and associate a logical hierarchy of URLs to them and perform the traditional CRUD operations by using the well-known HTTP methods (GET, POST, PUT and DELETE).

However, many systems have operations which don't quite fit into the CRUD paradigm. Say, I have a repository of persons. And say I have an id associated with every person which allows me to have nice URLs to each person as such:

http://example.com/persons/1
This URL obviously GETs me the details pertaining to person 1. Now what if I wanted this person to talk and walk. I can think of 3 approaches to designing this scenario:
  1. Operations as resources: Which means I can have URLs such as:
    http://example.com/persons/1/talk
    http://example.com/persons/1/walk
    However, walk and talk are obviously not resources and designing it this way might be considered unRESTful(?).


  2. Operation as a query parameter: This leads to URLs such as:
    http://example.com/persons/1?operation=talk
    http://example.com/persons/1?operation=walk
    A drawback of this approach comes to the fore if you need other parameters to perform an operation. So, for instance, if you had to specify what to talk or where to walk. You'll end up with URLs such as these:
    http://example.com/persons/1?operation=talk&what=Hello
    http://example.com/persons/1?operation=walk&where=North
    As you can see, with this approach you end up having resources with overloaded operations and parameters. And you have to be aware of these combinations yourself and also explain them to your users.


  3. Matrix URIs: Specify the operations using matrix-like URIs. With this, your URLs look as such:
    http://example.com/persons/1;talk
    http://example.com/persons/1;walk
    And you can specify the operation parameters using the traditional query string:
    http://example.com/persons/1;talk?what=Hello
    http://example.com/persons/1;walk?where=North
    With this approach you have 3 distinct ways of representing 3 different things - slashes (/) for hierarchical resources, semi-colons(;) for operations and query strings (?param1=val1&param2=val2) for parameters.

Although I like the clarity of #3, I haven't seen this approach used all that much. Which makes me reluctant using it myself. Are there any web systems out there that use this approach? Are there any drawbacks to this approach which is why it is not widely employed? Are there any other approaches to designing URLs for operations?

Many questions. Any answers?

Sunday, April 15, 2007

SOAP over DCOM in the ArcGIS ADF explained

The ArcGIS Server Java ADF supports accessing the ArcGIS Server over the internet (http) as well as locally (dcom). Internet access uses SOAP. Local access can work with the server objects directly over DCOM or you can also issue SOAP calls over DCOM.

For local access, the ADF gives preference to SOAP over DCOM while it accesses the ArcObjects directly over DCOM only when the functionality is not available thru SOAP. There are 2 primary reasons why SOAP / DCOM is preferred to ArcObjects / DCOM:

  • Performance
  • Code reuse

Performance:

When you work with ArcObjects / DCOM the server gives you access to remote ArcObjects proxies (such as IMapDescription, ILayerDescription, etc.). Every method call on these proxies is a remote method call. So methods such IMapDescription.getName() and ILayerDescription.getID() are both remote method calls.

On the other hand, when you work with SOAP / DCOM, only the methods defined in the WSDLs are remote calls. Once you have made those remote calls, you get access to objects which are local value objects (such as MapDescription, LayerDescription, etc.). So methods such as MapDescription.getName() and ILayerDescription.getLayerID() are both local method calls.

As you can infer, ArcObjects / DCOM elicits more "chattiness" with the server than SOAP / DCOM. And the reduced number of remote calls in case of SOAP / DCOM obviously translates to better performance over the lifetime of your application.

Code reuse:

If you look at various functionalities supported by the ADF such as AGSMapFunctionality, AGSGeocodeFunctionality, etc., the same functionality classes are used for both internet and local access. This was possible because these functionalities were implemented by using the SOAP interface to the server. The transport is HTTP in case of internet access and DCOM in case of local access but the code remains the same allowing us to reuse the same functionality implementation in both cases.

Capabilities such as the EditingTask which are not available with SOAP have obviously been implemented by using ArcObjects / DCOM.

Bottom line:

In summary, if your functionality can be implemented by using the SOAP interface you should use it. The richness of ArcObjects / DCOM is of course always available to you in cases where SOAP does not suffice.

Friday, April 13, 2007

What is REST?

There is a wealth of material out there on REST but very few that actually explain them succinctly enough for you to, well, pitch them to your manager in the elevator. Looks like someone has tried to do that and done a very good job at it:

Link: REST: the quick pitch

With REST, every piece of information has its own URL.

I'll use some of David's material myself and highlight the key REST concepts as bullet points:

  • [Of course] Everything is a URL: And what does that mean? Immediately all your information is readily accessible to everyone. It is cache-able, bookmark-able, search-able, link-able - basically it's intrinsically web enabled.

  • Think resources: With REST it helps if you design your system as a repository of resources. Not services. Not as a data provider - but resources.

  • URLs matter: You might argue that if it's machines that are calling into my REST resources, how does the niceness of URLs matter? Well, given that URLs are representations of resources and representations can be human readable text formats or browser readable html; your REST URLs are no longer just a privilege of machines. So URLs matter. Avoid query parameters as much as possible. You have a better chance of being indexed by search engines if you avoid 'em. Your implementation becomes easier. Refactoring is smoother.

  • POSTs are ok: In the ideal world all HTTP clients and servers would allow PUT and DELETE. But the world doesn't come to a standstill without these methods. Many have done just fine using POST and so would you.

  • Requesting content type in URLs is also ok: Again, in the ideal world, clients and servers could do content negotiation. And again, many have done just fine by specifying the format in the URL path or as a query parameter and so would you.

  • Consider JSON: JSON is simple. Parsing JSON is simpler. You don't even need to parse it if you are consuming it in a browser. You still want to serve XML given the huge support for it but JSON support is spreading every day and you'll benefit if you're a part of it.

  • Use HTTP as a platform: HTTP is not just a protocol. It's a platform. It already provides services such as caching, security (of course more could be done here), standardized status codes - benefit from them.


Is that all to it? Hardly. There's literally a whole science behind it. But that will do for now.

Thursday, April 5, 2007

Enough already... I need some REST

Like many others, inspired by Pete Lacey's S Stands for Simple, late last year I began to look into REST and by extension into HTTP, status codes, web caching, et al. In a nutshell I went back to the basics and discovered the wealth that I had turned a blind eye to what with the latest and greatest frameworks "abstracting out" what constitutes the web from me.

Suddenly the stateless nature of HTTP transformed from being a limitation to a virtue. The status codes weren't just numbers but a means of communication (in some cases even the lack of it - 304, anyone?). Caching wasn't something I needed to build but something I needed to learn how to use (ETag, If-None-Match, Cache control headers, what not). Ditto with security. URLs ceased being just names - they are a language.

It took all of that for me to realize that it's not the next WS* standard that will help me develop the next state-of-the-art web service but it's the existing goodness in HTTP, it's what makes the web work today, it's what brought you to this page and what enabled me to publish this page to the world.

Having relatively recently discovered REST I find it simple and natural. Simple is good. Natural is good. It uses the existing web / HTTP infrastructure not merely as a protocol but as a platform. And it fits into this Web 2.0 thingy to a tee: Issue AJAX requests(Actually it's more like AJAX without the X). Receive JSON responses. There's your secret sauce to building mashups.

This is not to say that I suddenly shunt everything that is SOAP and just do REST all the way. Far from it. SOAP has served me very well and I like it and I'll continue to use it. Something that lets me use pure Java / .NET while working with a piece of software half a world away from me is too precious to be ignored.

I believe that SOAP and REST are not contradictory but complementary. They have their own usages and users and they will coexist. And I'll continue to use them both as per my application needs. Horses for courses

I rest my case.