Sr. Director, Product Research, Epicor Software

Software Architecture

This blog is not associated with my employer.

Tuesday, August 08, 2006

ERP Data as Hypermedia

I work on ERP applications for a living, so I tend to see lots of ways business intent is manifested in an API. For the past few years, I’ve been trying out different architectural ideas to merge the success of the Web to enterprise application API development. The two aspects that have garnered the most payback have been (a) casting the data domain as a hypermedia set and (b) rationalizing constraints around GET, PUT, and POST to convey business intent and manage work. This blog entry is about (a). Making the data domain flexibly addressable is critical to workflow and EAI, which in turn makes it critical to SOA -- no matter how REST or WS-* might be utilized.

Most reasonably normalized databases already have clear semantics for referential data and child data. Reference columns link tables together by record ID. Child tables inherit the ID of their parent plus their own additional anonymous key value. The referential aspects form hypermedia-like links and the parent-child aspects provide document scope (not to mention the nice fit with XML).

Putting these together means that we can map a record as a URL using the same key values that identify records in a database. We can also extend the URL format across referential values. Here are some examples from an implementation we put out several years ago:

url://MySite/orders/101.xml returns the XML representation of order “101” in all its glory (details and all)

url://MySite/orders/101/1.xml returns just the first line item of order “101”.

url://MySite/orders/101/CustomerID.xml returns the ID of the customer

url://MySite/orders/101/CustomerID/Customer.xml returns the entire customer record for the customer identified in the “CustomerID” link

The last item is the most significant, because you can traverse the entire data domain – if the linkages exist – and access data many degrees of separation away from your starting point. We’ve been doing this for several years now in Business Process Management (BPM) architectures because the data one needs to make a business policy decision is rarely in the message. In other words, workflow-driven architectures need expression formats that bind the data in question with data already in the system.

For example, an administrator might set a policy to disallow orders for items belonging to a product class that itself is under approval hold by, say, the U.S. FDA.

url://message/orders/lines/items/holdnotices/fda.xml

Or, you don’t want to allow orders for customers on credit hold: url://message/orders/CustomerID/holdnotices/credit.xml

Note the “message” bit rather than “MySite” in the previous examples. The idea is to not only traverse entities in a database – it’s also to traverse from the message payload to the database in one expression. Non-programmers can actually read this and figure out what it’s doing. That capability is important in BPM because line managers control the policies in force. Line managers understand hierarchies like directory structures. The key is to keep the URN constructs uncluttered and simple.

That seems straightforward, but you have to work out how to pipeline referential constructs through the entity chain for multiple situations: inner-join, outer-join, existential, etc. You also have to work out how to constrain certain kinds of URLs that bring back too much data. Our initial work let you do something like this: url://MySite. It spit out every record in the database.

BTW, you can swap “.xml” for “.xsd” and get a schema for the results. You can also use “.htm” to get an HTML rendering. In fact, you can go to town with MIME types and style sheets to provide lots of viewable interpretations of whatever data is being sought. That’s pretty powerful.



Friday, August 04, 2006

Are GET and PUT Symmetrical in REST?

Does REST require symmetry? In other words, must the payload schema for messages I GET be the same as the schema for messages I PUT? I hope not, because (in my world) what I PUT is rarely a new, complete authoritative version of the data. In the work I've done, the PUT (or POST) payload explicitly indicates whether the item is new (in which case it is authoritative) or if I am changing an item that already exists.

The REST idea – in my mind – is that (a) you can address instances of data unambiguously and completely and (b) that what you GET and what you PUT (for a given URL) are semantically related -- but not necessarily exact copies.

Wednesday, August 02, 2006

Stephan's List: REST vs. SOAP

Stefan’s List is an interesting effort to categorize some very good bloggers into REST, SOAP, and (um) “either” camps. I know a few people on both sides of the isle and I don’t think any of them are on some sort of web-oriented death march. I mainly think about how business intent is most effectively expressed in message payloads – something neither REST nor WS-* are really helping with (it’s semantics after all).

My friend Paul Downey (http://blog.whatfettle.com/) of British Telecom (erroneously placed in the “wrong” camp in an earlier version of Stefan’s List) put together a brilliant slide deck (pdf) that unambiguously (and literally) illustrates his point of view about WS-*. I’ve been meaning to steal from it for some time. BTW, Paul is chairing a W3C working group to advise toolkits about mapping language constructs to XML Schema constructs – something that will help both sides of the WS isle. I think Paul’s working group will enable more XML Schema constructs to be supported in the mainstream, which in turn increases the vocabulary I can employ to represent my business intent.

REST Doesn’t Obviate WS-*
There is a VERY large IT constituency that relies heavily on modeling non-functional requirements. Pioneers have the luxury of trying these things out and mitigating the shortcomings as they go. Obviously, current enterprises want to extend their architectural core concepts into more open realms. But they need to prove that service-level requirements are achievable and that non-functional aspects can be modeled using approved best practices.

WS-* has grown around those needs. The specs provide CYA support for the big IT shops. I sometimes get upset that WS-* is no longer simple or particularly exciting. But people are often compelled into multilateral infrastructures and to make their complex interactions interoperable. There’s apparently a lot of money in achieving that.

PS. For the record, I use REST and tunnel it through SOAP and/or WS-* where needed.

Archive