A poisoned API

Every programmer knows what it's like to deal with a poisoned API. During development you make a decision that affects the design, structure, performance or suitability for a particular use. In time it turns out to have been a poor decision. Suddenly there's something in the application code, or worse, in the infrastructure code, that you're convinced is wrong. It pains me to explain to someone that they should use a rotten API when I know it shouldn't be there or ought to look different. Here are the options we have when that happens.
Let it rot
This is a way of dodging responsibility. Something's there and it works. It's badly designed, but you can live with it. It follows the rule “if it works, don't touch it.” I choose this approach only when there is no other option. If you're unhappy with a fairly isolated bit of code, preferably application code, that seldom gets used, leave it alone. If it's an exposed part of your infrastructure, forget letting it rot and consider the options below.
Wrap the interface
Wrap the original poisoned API in a new API. Unfortunately that isn't always possible because you can seldom isolate all the implementation details. In other words, if you have a poisoned API, the implementation is very likely poisoned too, and building a clean API around it will be hard. It still takes less time to implement and test than the parallel API method below.
Parallel API
If backward compatibility is a concern. You don't always know all the places the API is used, or you can't change them all. So you build a parallel implementation and interface. The new and poisoned APIs coexist peacefully. You can mark the poisoned API as deprecated. Unfortunately, the old calls are still there to haunt you. At some point you shut your eyes and rip it out.
Rip it out
This is the most radical answer to a poisoned API. Remove it completely and replace it with a new version. Prefer this approach whenever you fully control the codebase and backward compatibility isn't a serious problem. All three earlier methods are guilty of increasing your technical debt. The risk is that in time you may become dissatisfied with the replacement and find yourself back where you started.
Final advice
Refactoring and cleaning up code should be part of every developer's work. It's painstaking work that few people appreciate or give you time for. You need to allow for it if you want to avoid problems maintaining and developing your code. I prefer to rip out a poisoned API. Letting it spread into the rest of the codebase has almost always cost me far more than removing it early would have.
Related articles
Related CZ Podcast episodes
- #261 · Leadership
On leading people and teams. · Czech audio