Web Services Interfaces and Zero-One-Infinity Rule
Wednesday, 19 October 2005
I commented on Steve Vinoski’s blog:
Interfaces defining many kinds of messages imposes unnecessary coupling, when what is required is for documents to be thrown over the other side of the wall, leaving the other party to decide what order to parse and process the document.
To which Mark Baker posed:
So in the spirit of the Zero/One/Infinity rule, what is he saying? Is it a) services should not have interfaces, b) services should share a common interface, or c) services should have whatever interface they want?
My reply is: “I claim total ignorance of the Zero One Infinity rule” <wink>. By the way here’s a summary of the rule
A rule of thumb for software design, which instructs one to not place random limits on the number of instances of a given entity.
I’m struck by this apparent contradiction:
- as a programmer, I loath functions which have too many arguments since they make testing difficult, and are difficult to code to.
- Yet, with web services, I’m advocating a giant method which sends every parameter that is needed for the task to be completed, however many there may be.1
It boils down to this - metaphors are important. They define how we approach a subject. Documents are soft furry and small. Objects are slippery, slimy and have sharp teeth. Never mind that both are actually wild animals!
If web service is all about dealing with documents, it seems alright that we are dealing with 16 arguments. If a web service is about RPC, then 16 arguments feels onerous.
A doc-literal approach also guarantees us that we are dealing with a document, not a remote proxy. We are free to probe it, parse it and pull it apart knowing it’s just data2.
We also know that once the document is handed over, the customer isn’t going to suddenly say, “… wait and before you start…”, so both parties can have confidence that the entire context of the service is understood, or the state of the remote component is going to change.
1I suspect this difference is not that great in real life, as one would probably deal with relatively few structs which are marshalled across the wire
2when this data actually represents executable code, since it is a script that runs on your system
No. 1 — October 20th, 2005 at 4:47 am
Ok, but answer the darned question already! 8-)
Seriously, a, b, or c? Nevermind parameters, it’s interfaces I’m interested in.
No. 2 — October 20th, 2005 at 9:24 am
Mark, I wish I knew.
If I looked at WS through the eyes of a RESTafarian, I’d be saying - ONE interface: GET, PUT, DELETE, POST. I can live with that.
If I was the ugly sister of HTTP, I’d say ONE interface. Just put everything in a ENVELOPE and let me work it out. (Quiz: which ugly sister am I?)
Gee, now you are making me commit myself. Since I live in the real world, I’d say TWO interfaces. One that is so dead simple, it can’t possibly cater for more complex cases. The other one is able to cater for all complex cases, and is so difficult to implement, it makes life easy for one to convince people to use the former <wink>. The entire WS-* stack presents a combinatorial-sized-headache as far as guaranteeing interoperability. This is (probably) manageable when SOA is within the enterprise, but I honestly can’t see how organizations are going to be able to interoperate with the entire weight of the stack on something that should be kept as simple as possible. At this rate, it is cheaper to hire key-entry operators in the Philipines than to get consultants to automate the entire process.
No. 3 — October 20th, 2005 at 11:12 am
That’s a pretty good answer for not answering the question 8-)
I was hoping you’d say just “ONE”, because you already described the interface;
interface TheOneInterface {
Document throwOverTheWall( Document )
}
No. 4 — October 21st, 2005 at 11:44 am
Different people have different ideas of what constitute and interface though. A single OO-style interface with too many methods harkens back to the Corba days, hence I was really reluctant to talk about interfaces. The document that gets thrown over the wall in itself has to have agreed syntax and semantics, and to many that constitute an interface definition too.
It seems it is far more critical that:
a) the transport be dead simple
b) limit number of interaction to one
c) state request in terms of the result you require, rather than what you expect the service to do
example:
POOR
<add>
<number>2<number>
<number>4</number>
</add>
BETTER
<sum-of>
<number>2</number>
<number>4</number>
</sum-of>
Unfortunately, where people have to wrap CICS into a web-service, a single interaction can be pretty hard, especially if the business logic is buried in screens and screens of interaction. Perhaps this is why WS has grown so complicated.