There is now a great volume of material available on the Web comparing Web services built using WS-* stack technologies to those built using RESTful design principles. Just weeks ago, Burton Analyst Kurt Cagle offered us what practically was a short-course on RESTful web services design and its origins.
As I’ve mentioned in past posts, the HR domain is amazingly diverse. There are many back-office, computer-to-computer collaborations between HR trading partners for which the WS-* stack is still likely the best fit today and for the future. Yet on the other hand, HR also deploys a great and growing number of browser-consumable, computer-to-human services. In fact, the diversity of requirements is such, that one can easily imagine a company having both types of interfaces even for the same underlying resources or services (e.g., a WS-* based back-office service for handling high-volume, computer-to-computer submissions of job postings as well as a RESTful service to handle human-initiated job postings from a business-partner’s website). So it is realistic to expect these two approaches for web services to live side-by-side within the same organization. This leads to the premise behind of this post, which is that if you are faced with supporting both these web services design styles, or if you are looking for architecture that could help you migrate from one-style to the other, there are some patterns within the forthcoming HR-XML 3.0 architecture that could be helpful.
Where We’ve Been
A recently revised set of WSDL’s for HR-XML’s 2.5 Assessment specification is illustrative of our design approaches within the 2.* series of releases. There are two WSDLs: One for a service hosted by the customer and the other for a related service hosted by the provider. These aren’t normative, rather, they are intended as “starter-kit” templates for implementers. The WSDLs import types from the HR-XML Assessment schemas, wrap those types in messages defined within the WSDL target namespace, set out operations (input/output/fault, etc.) within a PortType, bind those operations to SOAP, and then provide a place for implementers to specify a network endpoint to which requests would be sent.
You can characterize the definitions within these WSDLs as being more “activity-based” than “resource-oriented.” The example I’ll carry through this post is the retrieval of an assessment order status. In the 2_5 design, this is accomplished using a “GetAssessmentStatus” method. The input is a GetAssessmentStatus message, which brings in the hrxml:AssessmentRequestType. This is a special-purpose type with just the thin bit of data you might need to retrieve an assessment status (most importantly an OrderId). The output is a “ShowAssessmentResult.” In the output, either a status is returned, or, if one is available, the completed assessment result.
Where We Are Going
You can’t really describe the Business Object Document (BOD) architecture within HR-XML 3.0 as “RESTful,” but it is fair to characterize it as “resource oriented” (at least compared to the “activity-oriented,” RPC approach covered above). A BOD is a message that creates a “business object” or reads, updates, cancels (etc.) such a business object. Rather than use a special-purpose message to request status, the usual approach using BODs would be to take the “noun” representing the object/resource in question and combine it with the appropriate verb type from the OAGIS library. Rather than using the special-purpose message to call a particular method (e.g., GetAssessmentStatus), the HR-XML 3.0 noun contains all the properties necessary to fulfill the purpose of the particular business object, including a “Status Property.” So using the BOD approach, you’d combine the standard OAGIS “Get” verb together the AssessmentReport noun into a GetAssessmentReport BOD. The response to a GetAssessmentReport would be a ShowAssessmentReport. An XPath within the Get verb’s expression element would be used to set the scope of what you want evaluated or considered in processing the request. An action code communicates what is to be done within that scope. Then fields such as OrderID are used within the noun to specify a particular order (Order no 1234) to retrieve. In the BOD syntax, this might look like so:
<GetAssessmentReport
systemEnvironmentCode=“Production”
releaseID=“1″
versionID=“0″
languageCode=“en-US”
xsi:schemaLocation=“http://www.hr-xml.org/3
http://schemas.hr-xml.org/xc/canon/3.0/BODs/Developer/GetAssessmentReport.xsd”
xmlns=“http://www.hr-xml.org/3″
xmlns:oa=“http://www.openapplications.org/oagis/9″
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”>
<oa:ApplicationArea>
<oa:CreationDateTime>2007-04-05</oa:CreationDateTime>
</oa:ApplicationArea>
<DataArea>
<oa:Get uniqueIndicator=“true” maxItems=“2″>
<oa:Expression expressionLanguage=“XPath”>GetAssessmentReport/AssessmentReport</oa:Expression>
</oa:Get>
<AssessmentReport>
<OrderID schemeID=“Test Order No” schemeAgencyID=“AssessCo.com”>100-777999-33</OrderID>
</AssessmentReport>
</DataArea>
</GetAssessmentReport>
So compared to the 2_5 approach, there are no special-purpose messages. Broadly speaking, requests are fashioned and fulfilled by setting a scope within the associated business object, specifying the action to apply, and including necessary field values. See the slide deck from the “BOD Mechanics” session at HR-XML’s Atlanta meeting for an in-depth treatment of this subject.
Getting RESTful
The public API for a RESTful web service principally is a set of URIs. This set of URIs, when properly designed and conceived, becomes “a resource architecture.” Basically, the idea is to come up with a URI template scheme that allows you expose a URI for every piece of data that your users or trading partners need to operate on. In other words, the URI, like the XPath in the above BOD scenario, sets the scope of what it is that will be operated upon or considered in a particular interaction. The idea of one URI for each piece of data is a significant departure from the WS-* style of web services, in which there is typically a single URI designated as the network endpoint to which many different types of method requests go.
RESTful APIs often are presented in a matrix-style table format, which indicate the URI template to use with which HTTP verb to accomplish particular types of outcomes (e.g., creating new resource instances, reading the state of resources, updating resources, etc.). Like the BOD approach, there is a separation of verb and resource instead of building semantics into a special-purpose method request. So to carry through the AssessmentReport example introduced above, a RESTful implementation might rely on a URI template like the one below:
http://www.reallygoodassessments.com/v1/AssessmentReport/{OrderID}
So to get a status or retrieve a completed report, you’d use an HTTP Get and insert the particular Order ID within the URI template:
http://www.reallygoodassessments.com/AssessmentReport/1234
If you compare the BOD example to the REST example, there are a few things that drop out. For example <oa:Get uniqueIndicator=”true” maxItems=”2”> There’s on-going discussion about service descriptions for RESTful services. Web Application Description Language (WADL) is one format proposed for such descriptions. WADL is intended as a service contract, much like WSDL for WS-* stack web services. It occurs to me that conditions governing a GET, such as the above-referenced “unique indicator” and “max items,” might be the things you’d specify in a WADL or that might otherwise be relegated to interface documentation or trading partner agreement.
Any Parallels?
Are there any patterns in common between the BOD and RESTful approaches that could be leveraged in providing BOD implementers a path (no geek pun intended) to RESTful web services? I think there are. Consider the “BOD Mechanics” deck that I’ve referenced a few times. If you gave a group of REST-knowledgable architects the set of definitions that appear beginning on page 45 for data management using BODs, I’d guess most would find the raw material they’d need to derive a resource architecture and associated RESTful API.
One thing I find interesting is the correlation in purpose of the URI template within REST and the expression used within an OAGIS verb. Basically, each is setting the scope of what part of a business object or resource will be evaluated or considered in applying an action. REST uses an URI. The BOD uses an expression such as XPath. I have to imagine this similarity in purpose and structure could be useful in managing RESTful and BOD-based interfaces in parallel or in migrating a service from one to the other style of interface. The other quality of OAGIS BOD architecture that strikes me as reasonably parallel (versus perfectly parrallel) is the considerable restraint and discipline the OAGi community has used in avoiding the proliferation of verbs and in avoiding verbs that are overloaded with complex business semantics. OAGIS verbs are course-grain verbs. While OAGIS verbs include some business semantics that go beyond the RESTful HTTP verb set, I’d think you’d find that many OAGIS implementers use a relatively small subset of the OAGIS verbs and would be able to do the necessary mapping to HTTP verbs.
I expect that this is a topic HR-XML and other groups using the OAGIS BOD architecture will begin to explore in earnest next year (I think HR-XML has enough on its plate this year!). Based on my observations and correspondence with architects with some of HR-XML’s peer standards organizations, I expect in the not so distant future, you’ll see more vertical business standards groups looking at supporting RESTful variations of their standards.
Tagged BODs, HR-XML, REST, RESTful, RPC