At work I’ve been tasked with consuming a new internal web service for one of our sites. It’s been anything but simple. However, the issues, like normal, aren’t technical. The biggest problem really boils down to a communication issue. And really, it’s not so much a problem of communicating between developers, but communication between the service and the consumer. By that I mean, there is a problem with the amount of data that is being communciated.
The team working on writing the API/service for us seems to have taken the approach of “What data does our database require? Ok, ask the consumer for ALL that data.” An example might be helpful here. For this example, we’re a book seller. That’s all we sell. We want to use this new service to manage ordering an item. We might expect to pass to a service the ISBN, the quantity, the date the item was ordered and the user who ordered it.
The problem is, our API wants to be “flexible” so it exposes all sorts of information. While you might expect a method like OrderItem(string ISBN, int quantity, DateTime orderDate, string username), what we actually have is OrderBookForCustomer(Book bookToOrder, int quantity, DateTime orderDate, User customer). That looks all well and good until you realize you have to populate all those objects.
Our objects look like this:
*notice that several of these properties are themselves objects
Now our little method call with 4 parameters still only has 4 parameters, but we (as the consumer) have a myriad of options of what should be sent. For the Book object we’re passing in, how much data is required? Can we just set the ISBN and pass that in? If we set the ISBN and the Title but they don’t match, which value will the service choose to go off of? For the user we have not only their user name and password, but also their address. If we pass this information in will the service use it blindly? Or will it compare it to the address it has on record for the user?
As you dig deeper you realize all you want to do is order a book. You want to ask this order service to handle all the nitty-gritty of looking up the customer address, calculating the cost, finding the correct title for the book etc. And in reality, the service is doing it. But from the method signature and available possibilities, it’s impossible to tell that.
What’s interesting, though, is how this problem isn’t limited to the Service/Consumer domain. How many times have you set in a meeting and asked a question like “Where does this user get authorized?” Only to have someone go into the philosophy of the authorization process. Usually prefacing his discussion by saying “What you need to understand is…”
I’m probably as guilty of this as anyone. I like numbers and thinking out loud. My wife likes answers. Say we’re looking at a new bedroom set for my daughter. She has kind of a funky shaped room and one wall has built in bookshelves. As a result, she only has 2 walls she can put stuff on. So we’re looking at a bed and desk combination. My wife asks “Will this fit in her room?” The correct answer is either “Yes” or “No.” However, I can’t tell you the number of times I’ve responded with something like:
Let’s see… the bed is 80” long and the desk is 18” deep, so that’s 98” total. Her one wall is 98” so it would fit there but she couldn’t actually use the desk, because there’s no space to sit down. On the other hand, if we put the bed along that wall and set the desk next to the bed it would fit. Then we run in to the problem of the desk blocking part of the window, because the desk is 30” tall and the window in that room is low, so it could block part of that window. Also that way might block the door from swinging ALL the way open. But it should still open about 90% of the way.
I’ve told my wife a ton of things in that statement, but I haven’t communicated. She still is unsure if the set will fit in the room in a way that isn’t blocking traffic flow.
So too with our API. It’s providing us with 40 pieces of information we CAN fill out, but only 4 that we NEED to. It would be better from the consumers standpoint to ask for the information they require and populate the rest behind the scenes (e.g. get the ISBN from the consumer, and look up the title.)
In the end, communication is about the data you need, not the data I have.