3 ms·
Rich Hickey had a very interesting talk a while back about breaking changes titled Spec-ulation that I highly recommend watching. HN discussion: https://news.y
by bringtheaction 9y ago
Rich Hickey had a very interesting talk a while back about breaking changes titled Spec-ulation that I highly recommend watching.
HN discussion: https://news.ycombinator.com/item?id=13085952 https://news.ycombinator.com/item?id=13085952
I think it was he who talked about maintaining old versions not by backporting bug fixes but instead by rewriting the old version to be a thin layer that gives you the interface of the old version upon the code of the new version. That, my friends, is how you can provide the old interface without the engineering overhead of maintaining billions of different versions of your codebase IMO.
It goes like this: First you have v1. Eventually you make v2. Now you write a translation layer that you replace v1 with that has the same interface as did v1 but which transforms arguments passed to it as necessary before passing them on to v2 interfaces and likewise transforms the result as necessary.
Now when you get to v3 you don’t rewrite v1, only v2. So requests to the v1 endpoint will go v1 -> v2 -> v3 and back. This means a bit of extra computational overhead but it will certainly be worth it in terms of the engineering overhead saved.
- timvdalen 9y agoThis is how Stripe handles it as well: https://stripe.com/blog/api-versioning https://stripe.com/blog/api-versioning
- ChrisSD 9y agoIn practice that isn't quite as simple as you make it sound. People come to rely on bugs, weird edge cases, undefined or undocumented behaviours in v1 so you end up having to spec and replicate them in your v2 shims. Convincing people to stop using libraries in such a fragile way would be the real trick.
- swsieber 9y agoYou can sort of do this in rust too, from a programming language point of view: https://github.com/dtolnay/semver-trick https://github.com/dtolnay/semver-trick
- ezyang 9y agoIn an old draft of my post I called this out more explicitly. There are two things worth thinking about. First, if you think about actually doing this in a traditional programming language, you can quickly see that this is going to result in a lot of boilerplate. REST APIs make this a lot easier, because it's easier to say something like, "change the meaning of this command, but have everything else stay the same." Functions and classes are not setup for this kind of metaprogramming. Second, sometimes you are breaking BC because the old behavior is extremely inconvenient to provide under a new internal implementation. This is pernicious, because "I didn't like the old function name" is not a good reason to break BC, but "I can't rewrite the internals and support the old functionality" is a good reason to break BC. So you're in a situation where your mechanism for maintaining old versions breaks down /precisely/ when you would have gotten the most utility from breaking BC.