Yak Shaving is a Good Way to Improve an API
- (idiomatic) Any apparently useless activity which, by allowing you to overcome intermediate difficulties, allows you to solve a larger problem.
- (idiomatic) A less useful activity done to consciously or unconsciously procrastinate about a larger but more useful task.
Both interpretations of the term Yak Shaving as explained by Wiktionary are absolutely accurate descriptions of most refactoring jobs. The Yak Shaving in refactoring itself can be described by this gif showing what happens when you want to change a light bulb:
However, when developing an API, it’s not such a bad idea to perform actual Yak Shaving (only the first interpretation, of course). Let’s look at an example why, from the daily work maintaining jOOQ.
The Task
For jOOQ 3.6, I wanted to implement a very simple feature. Feature #2639: Add stored procedure OUT values to DEBUG log output. This is not an important feature at all, but certainly very useful to a lot of jOOQ users. The idea is that every time you run a stored procedure with DEBUG logging activated, you’ll get the OUT parameters logged along with the procedure call. Here’s a visualisation:
Now, the actual implementation would have been very easy. Just about 10 lines of code in the existing LoggerListener that already takes care of logging all the other things. But there were a couple of caveats, which reminded me of the above lightbulb changing gif:
The apparently useless activities
- There was no way to access the RETURN_VALUE meta information of a jOOQ Routine
- There was no easy way to access Routine IN and OUT values generically
- There was lifecycle event that modelled the moment when OUT parameters are fetched in jOOQ
- There was no way to format Routine OUT parameters in a nice way
Does this feel familiar? There is need for refactoring!
@lukaseder Someone sent this to me to explain it. pic.twitter.com/ZBr06UlAir
— Jason Herr (@herr_jason) March 2, 2015
Now, this whole implementation is hidden in jOOQ’s internals. It wouldn’t matter too much for users, if this had been hacked together in one way or another. For instance, obviously the RETURN_VALUE meta information could be accessed through internal refactorings, the same is true for IN and OUT values. There are other lifecycle events that might have worked just as well, and formatting is easy to re-implement.
But this is a popular API that is used by many users who might profit from a cleaner solution. Thus, why don’t we simply refactor and implement:
- Add a public Routine.getReturnParameter() method
- Add public Routine.getValue() and setValue() methods
- Add ExecuteListener.outStart(ExecuteContext) and outEnd(ExecuteContext) to capture fetching of Routine OUT parameters
- Add Routine.outRecord() and Routine.inRecord() to view a Routine as a Record”
The thing is:
The API implementor is the first API consumer
It’s hard to foresee what API users really want. But if you’re implementing an API (or just a feature), and you discover that something is missing, always consider adding that missing thing to the public API. If it could be useful to yourself, internally, it could be even more useful to many others. This way, you turn one little nice feature into 5, amplifying the user love.
Don’t get me wrong. This doesn’t mean that every little piece of functionality needs to be exposed publicly, au contraire. But the fact that something is keeping you – as the maintainer from writing clean code might indicate that others implement the same hacky workarounds as you. And they won’t ask you explicitly for it!
Don’t believe it? Here’s an entirely subjective analysis of user feedback:
- 0.2% – Hey, this is a cool product, I want to help the owner make it better, I’ll provide a very descriptive, constructive feature request and engage for the next 5 weeks to help implement it.
- 0.8% – Whatever dudes. Make this work. Please.
- 1.3% – Whatever dudes. Make this work. ASAP!
- 4.0% – WTF is wrong with you guys? Didn’t you at least think about this once??
- 4.7% – OK, I’m going to write this completely uninformed rant about this product now, which I hate so much. It makes my life completely miserable
- 9.0% – Oh well, this doesn’t work. Let’s go home, it’s 17:00 anyways
- 80.0% – Oh well, this didn’t work yesterday already. Let’s go home. It’s Friday, 16:00 anyways
Now, most of this list wasn’t meant entirely seriously, but you get the point. There may be those 0.2% of users / customers that love you and that actively engage with you. Others may still love you or at least like you, but they won’t engage. You have to guesstimate what they need.
So. Bottom line:
If you need it, they probably need it. Start Yak Shaving!
Reference: | Yak Shaving is a Good Way to Improve an API from our JCG partner Lukas Eder at the JAVA, SQL, AND JOOQ blog. |