Agree in theory, in practice this is impossible. Even if you're an absolute domain expert in whatever you're doing, software and requirements will evolve and you will end up needing to implement something for which your current API is not suitable. Just ask S3:ListObjectsV2 or golangs' `encoding/json/v2` etc.
I push back hard on this one because a lot of developers will try to be "clever" and basically turn their api into
or an equivalent, and now you have an API which theoretically can handle any requirement, but does so in a way that's extremely unfriendly and painful to use.
It's better to accept that your API will change at some point and have a versioning and deprecation strategy in place. With well-architected software this usually isn't hard.
Yes, and also don't try to anticipate everything by implementing features that won't be used soon, ie "just in case". If the soon turns to never, any unused feature is basically dead code and represents future costs and constraints to maintain or remove it.
The most sustainable approach is designing APIs with explicit extension points and versioning mechanisms from day one, rather than trying to predict all future requirements or resorting to overly generic interfaces.
That’s not how I read “Don't ever implement good-enough-for-now APIs”.
Requirements _may_ change, but it’s much harder to have consumers move to a new API. Once it’s published, it’s a contract you don’t want to break.
That doesn’t mean you need to design an extremely flexible and future-proof API to the point it stops making sense — it’s a false dichotomy.
What you can do is take your time designing an API that still makes sense as long as possible, until your understanding of the domain has changed so much that it’s a different shape altogether.
Throwing your hands up and saying “it’s impossible” is easy, the art is in figuring out how much has to change until you have to say that.
Design is a game of push-pull between context and form, and you can add tolerances both ways.
Another way to put it: Software isn't just stale building blocks, it's an ever evolving ecosystem with varying lifetimes. Developers should embrace the different periods during the lifetime of software, and model with them, not around them.
Yeah, it’s too hard of a rule. In reality interfaces have points of resistance; where they aren’t really helping you do what you’re wanting, and they have fitting-points where they do what you need done.
I’d argue it’s your job to strike some kind of balance there. If you know you’re working with something stable, why settle for good-enough? Well, because the task of assessing what is stable requires years of mistakes, and good-enough varies drastically between languages. I think I see a point here for using primitive C; there’s hardly a type-system to waste time with, but you can cut yourself with macros. This is why I use Odin.
I’ve never once seen “come back and fix with deadline” work. It’s really only the “with deadline” that does not work. Good teams will constantly be judging if now is the right time to fix the thing, and that fluid process works pretty well. Setting deadlines for tech debt just leads to the people setting the deadlines getting upset and quitting when they are inevitably missed. Save the urgency for when it’s warranted, like discovering a time bomb in the code, a scaling limit that is about to be breached— people will take you more seriously, you will be happier, they will be happier, hooray.
By all means, shoot for absolute perfection on your own projects. I work very, VERY differently on my own code than I do on work code, and I get different types of satisfaction out of both (though of course massively prefer working solo).
I’ve implemented APIs with routes like `/temp-get-order` in an attempt to force a return and even then we never returned to it. Like you’re saying it was eventually deemed insufficient for reasons outside of it being imperfect and that’s when we finally replaced it. Maybe places with more resources or discipline can manage otherwise but I’ve never worked somewhere that can.
That only works with product teams, in consulting it is either done alongside the ticket or it is gone forever, there isn't even any guarantee who will stay around after the delivery cycle is done.
And the new team might not even be allowed budget to fix those issues, and better not spend hours that do not fit tickets on the Excel budget plan.
Agree in theory, in practice this is impossible. Even if you're an absolute domain expert in whatever you're doing, software and requirements will evolve and you will end up needing to implement something for which your current API is not suitable. Just ask S3:ListObjectsV2 or golangs' `encoding/json/v2` etc.
I push back hard on this one because a lot of developers will try to be "clever" and basically turn their api into
or an equivalent, and now you have an API which theoretically can handle any requirement, but does so in a way that's extremely unfriendly and painful to use.It's better to accept that your API will change at some point and have a versioning and deprecation strategy in place. With well-architected software this usually isn't hard.