Pretty wild that none of this talks about testing or observability. Tests are also something that you need to pay to maintain, but they give the ability of reducing the risk that you broke something when you removed it. Additionally when you've exposed your service to potential external callers you need to both have a robust way of marking some calls as deprecated, to be deleted as well as observing whether they are still being called and by what.
I recently did our first semi-automated removal of exposed graphql resolvers, metrics about how often a given resolver was already available so parsing that yielded the set of resolvers I *couldn't* delete. Graphql already has a deprecated annotation, but our service didn't handle that annotation in any special way. I added observability to flag if any deprecated functions have been called & then let that run for sufficiently long in prod, then you can safely delete externally exposed code.
This is going to be a bit of an oversimplification but when you build things that are easy to delete, then you’re not going to cause unintentional bugs when you delete them. It’s once you over complicate things that everything becomes an interconnected mess where developers don’t know what sort of impact changes will have. There are a lot of ways to fuck this up of course. Maybe you’re following some silly “best practice” principle, maybe you’re doing “micro-services” in a manner where you don’t actually know who/what consumes which service. But then you’ve not build things that are easy to delete.
I think external consumption as you frame it is a good example of this. It’s fair to give consumers a reasonable warning about the depreciation of a service, but if you can’t actually shut it off when you want to, then you’ve not designed your system to let things be easily deleted.
Which is fair. If that works for you, then so things that way. I suspect it may not work too well if you’re relying on tests and observations to tell you if things are breaking. Not that I have anything against tests, but it’s not exactly a great safe-guard if you have to let them tell you if you broke something in a long complicated chain. Not least because you’re extremely unlikely to have test-coverage which will actually protect you.
If you write so many lines of code then you can expect some other number of lines of tests. If you delete some of the code, you may be able to delete some of the tests. The point is that you can talk about just the code like TFA does and assume related impact on tests. TFA not saying anything about tests does not let us assume that TFA means that one should not write tests.
I recently did our first semi-automated removal of exposed graphql resolvers, metrics about how often a given resolver was already available so parsing that yielded the set of resolvers I *couldn't* delete. Graphql already has a deprecated annotation, but our service didn't handle that annotation in any special way. I added observability to flag if any deprecated functions have been called & then let that run for sufficiently long in prod, then you can safely delete externally exposed code.