Expanding your RESTful architecture with ArcGIS Server

Author's Note: After I originally posted this write up, I got a good comment from Sean Gillies (see comments to this post) with a couple important notes in it.  First, I let SOAP and WS-* terminology bleed into my discussion of REST when I referred to a "REST endpoint".  Once it's RESTful, it's a resource, not an endpoint.  In addition, he called attention to an error in the example REST URI I provided (http://mywebsite/roadPoints/create).  Since we're not creating a new state on the server side, the correct request is a GET.  See Sean's comment for more info.  Sorry for the errors in the original post. During the ESRI Developer Summit last week, Dave and I both talked about some principles and methodologies in a RESTful architecture that we've used in several scenarios here at DTS, when the use of the ESRI-provided ArcGIS Server REST API either doesn't offer the functionality needed to accomplish a required function, or the REST API is not optimal in accomplishing that function. 

What you can't do, and what you can do better

When we look at the functionalities exposed by the various ArcGIS Server-side APIs, we see a trend that looks something like the following diagram.
Media_httpbriannoylef_bcnii
The SOAP API offers a subset (albeit a very large one) of the aggregate functionality offered by ArcGIS Server, while the REST API offers a subset (and still a pretty impressive one) of the functionality exposed by the SOAP API.  (FWIW there was some chatter at the dev summit that the REST API would eventually be functionally equivalent to the SOAP API.) Not surprisingly there are simply some things you cannot do via the REST API and since our preferred approach is to access ArcGIS Server via the REST API whenever possible, we frequently need an alternate solution. In addition, consider the following scenario: As a developer, I need to implement functions that allow the user to locate a point along a linear feature by "click" on the map with a minimum of friction.  The actual GIS of our theoretical operation might look something like this:
  1. Take a user specified point and buffer it
  2. Reproject the buffer to a different spatial reference and hold on to the geometry
  3. Use the reprojected buffer geometry to intersect a roads layer and get a road
  4. Use the road polyline geometry and find the distance along the road where the buffer first touches it
  5. Use the distance to "cut" the new polyline to produce a new polyline feature describing the affected road feature up to the point of intersection
  6. Return the polyline geometry and the distance along the polyline to the client for rendering
Sure this is just an example to make a point, but it makes it well.  Our RESTful service calls look something like the following diagram.
Media_httpbriannoylef_hkptr
Pretty chatty eh?  Does the user care about the GIS involved...no.  They want to click the map, have a portion of a road segment highlight, and they want to see a mile marker value.  With so much going on in the client, business logic is bound to slip in: When the client get's one of those individual responses back, how does the response get validated before continuing along the operation chain? How do you unit test it if it resides in the client?  In addition, while RESTful architectures are definitely performant in the main, all this chatter on the wire suffers from latency; latency in transfer and latency in serialization/deserialization at the endpoints. And there is a better way.

Getting your REST, and still getting something done

Consider the following diagram which should look familiar to those of you who attended Dave's talk Thursday morning last week.
Media_httpbriannoylef_hcgut
Let's take a closer look at what's going on.
  1. In our example architecture, the user "map click" initiates a call to a RESTful URL (e.g., http://mywebsite/roadPoints/create http://mywebsite/roadPoints/get or http://mywebsite/lineclipper, etc.) on the web server
  2. IIS hands off our X,Y coordinate to ASP.NET MVC.  The Routing engine in turn directs the request to the Create GET method on the RoadPoints controller. By the way, an MVC controller method is just a convenient and cogent example; any RESTful service endpoint REST resource will do (WCF, etc.). The point is to make this first hop look RESTful to a client application.
  3. Our MVC Controller uses SOAP to call a traditional WS-* web service on the ArcGIS Server box.
  4. The web service on the ArcGIS Server box uses an ADF connection to access a COM Utility or SOE running inside a SOC process
  5. Our custom COM utility or SOE does all of the buffering, reprojecting, intersecting, etc. (all the GIS "stuff" we're hiding from the user) using ArcObjects
  6. The result is returned to the web server, converted to JSON by the controller class, and is sent back over the wire as JSON for rendering in the client.

What it gets you

In short, we've abridged the six step GIS process described near the beginning of this post to: "Here's a point, hand me a road segment and a mile marker." We've transferred what would have been client workload into an MVC controller class and a web service on the server side, reducing chatter on the wire, increasing performance. We've left the GIS in the hands of custom ArcObjects code (read: fast).  In addition, we've done two other important things:
  • Encapsulated business logic where it belongs
  • Increased testability of our application by keeping complex functionality out of the client

But what about..?

Some of you may be thinking "Wait just a gall-dern minute! I see SOAP, WS-*, and ADF in that diagram."  Horse-pucky I say...the guts don't matter.  All that matters is how you surface the original request for the client.  The client sees a REST endpoint resource, and get's the answer the user wants quickly.

Conclusion

Much has been written in the ESRI realm about the power and utility of COM utilities and Server Object Extensions (SOEs).  Don't assume that the RESTful nature of your architecture needs to stop where the ESRI REST API or the ASP.NET MVC toolbox does.  That's the beauty of REST...bolting together high performance, URI-based services and application components that may or may not be of your own making.  Surfacing custom server side components in this way provides an excellent means to providing focused, high performance applications with advanced capabilities not currently available in the ArcGIS Server SOAP and REST APIs.  This approach encapsulates (hides) complexity from the user, is highly performant, and represents a simple reorganization of technologies most of us geo-geeks are already used to using.