I think one of the hardest things I’ve had to do, aside from keeping up with emerging technologies at a pace that “relatively” parallels the speed it crops up, is thinking about and designing how a service will communicate with its potential clients. Perhaps I put a lot more work into this than what would normally be necessary but I feel like communications between clients and services should be seamless and cohesive not only in syntax but in conceptualization so that it’ll make sense both in text and on a whiteboard.
Perhaps it’s more of a side effect of my never ending quest for geometrically sound aspects in ever facet in my life.
Designing a service, for me, has always been a two-tier process in which both tiers run nearly parallel with each other. Not only do I need to clearly define what it is the service should be doing, but I want to make sure that a client can effectively communicate with the service such that the request is precise and that the interpretation by the service is just as clear.
Now I know what you’re thinking already – well this is common sense when designing a service. Duh!
Maybe. But have you seen the service contracts that are implemented internally in your organization? Can you discern, simply from reading the contract, what the service is supposed to do, what a client can expect from it when asking a specific question, what type of information is expected from the service depending upon the question you’ve asked it, how it’s going to deliver that information back to a client, and how that service is going to handle potential exceptional cases during the work requested (printing stack trace is not acceptable for deliverables).
Admittedly, some of this can be solved with solid documentation. But good documentation isn’t an excuse for piss-poor syntax. Perhaps a little more thought is required.
I think things became a little more clear to me when I started conceptualizing client-service interaction as a conversation. A really robotic and droned conversation but one all the same. Similar to the way network communication is conceptualized with ACK and SYN. It created way more work than before but I think the end result is worth the effort.
Obviously, the first hurdle is figuring out what your service is supposed to do. Really break down all of the possible tasks that this work can be compartmentalised into and make sure that each of those tasks is very well defined. Not only is it important that the work is done as accurately as possible but you have to remember that the signature of the function is going to be what a client is going to see when it “asks a question.” So the entire signature has to be concise. For these cases, I’m usually a little forgiving if the identifier is a little long-winded but so long as it’s not something like
function a(a, b, c, d, e, 2, smileyFace)
So how could a client ask a question of the service? This question ties in directly with my previous point. I model this like a user story almost.
“I’m Client A, I want to do this so how do I ask for it?”
“I’m a Patient Directory Client, I need patient records for display, how do I ask for it?”
“I’m a greedy child Client, I need fifty ponies for Christmas, how do I ask for it (and actually get them)?”
Along with this, a client should be readying itself for the the delivery of the return information from the service. The key here is that the client has an expectation of what it needs and the service should provide that.
Implementation details can get muddy here and it’s all specific to your problem domain and choice of language. Typically throwing strings around is a sane bet for really stupid simple data. Complex objects can be encapsulated in more robust specifier formats like JSON and XML. Really complex objects, like instances where a client may expect a service to provide it with a container of complex objects, can be a little more difficult to handle especially when you’re solution is multi-threaded. Again, this is all reliant on the programmer’s knowledge of the language and problem domain.
One last thing – naming convention. This is critical. You should not have multiple services in production that exist on the same server that either have function names that are all cased differently, that reference argument or cached data using KVP with keys that are defined with different semantics (i.e. “CreateDate”, “Create_Date”, “create_date”, “create_Date”, “Create_date”, “createdate”, “createDate”, “create_date”) <—- Yes I’ve seen this before. Or that expect specifier formats like JSON or XML and use equally disturbing names in tags. This is all bullshit and it’s more confusing than helpful. Ensuring that a formal naming convention is standardised and implemented before hand is crucial to ensuring that the service contracts are built solidly from the start and future maintainers have something to work with later on down the road. And if they’re good programmers, they’ll follow the convention unless it’s detrimental to the domain.