I am maintaining a public API and have to deprecate a method.
Is there a general rule on how many months/years/versions before the deletion I should deprecate a method?
At minimum, you should keep deprecated methods in one version before removing them which seems kind of obvious when I write it out. I don't think there is a maximum time but if you never actually remove them, deprecation becomes a little pointless.
Major version releases are a good time to remove deprecated methods. Minor releases should typically not contain breaking changes. As cHao has noted in the comments, deprecation doesn't necessarily imply that there will be an eventual removal so if you plan to remove things after deprecation, you should explicitly note that and provide some guidance on the timeline.
This depends solely on what kind of stability guarantees you gave to your users, and how much pain you want to cause for your users.
Ideally, your API uses semver so that any breaking change causes the major version number to be incremented. In practice, it is desirable to do this almost never. If your API is installed via some package manager, you may want to create a new package name after a breaking change so that a simple upgrade doesn't cause conflicts (e.g.
myapi2 v2.123.4 vs
myapi3 v3.2.1). That may be unnecessary if your package manager supports tighter version dependencies (e.g. a dependency specification like
~v2.120 that does not include
v3.*), but different package names have the advantage that incompatible versions can be used side by side very easily. Even when using semver, it can be sensible to have a deprecation period.
Semver is not always applicable. Then it is more important to communicate a clear stability policy. For example:
Such policies work particularly well when you have regular releases so that there is a clear deprecation period, e.g. one year.
Aside from marking any parts of the API as deprecated, you should make the deprecation widely known. For example:
As for the exact deprecation period to choose, first look whether you have to honor any support contracts with your users. Such contracts may require you to maintain compatibility for some period. If not, consider any downstream impact. Try to change less rapidly than downstream users so that they can go through a deprecation cycle of their own. Downstream users will take some time to adapt to your changes, so you should never have a deprecation period shorter than a month.
Ideally, you would want to wait until no one is using the deprecated method anymore. Considering you're using a public API, that's easy to track, but you might end up waiting a very long time.
in 2015, Google had a similar issue with the stlport API on their Android OS. They had deprecated it and wanted to remove it, but tons of apps were still using it. They found a clever solution:
Essentially, they added an 8 second sleep() during the bootup of any app which still used the API with an appropriate log message for the developers. A month later, they doubled it to 16 seconds. then another month later, they could safely remove the API interface because no one was left using it.
This can be a very effective way of doing this. The only real issue is if your API is very old and has actively used consumers that are no longer actively supported. Unfortunately, you probably won't be able to fix such consumers yourself, but at that point you can't really do much more than delete the method and break the consumer.
The minimum time for providing deprecated methods depends on the development cycles of programs using your API. As a ballpark figure, 1 year should be enough.
As for the maximum time before you have to remove deprecated methods, I'd argue that there is no such thing. No matter how long you wait, removing a deprecated method will always break something. Some programs using your deprecated API are not actively maintained, and breaking compatibility will mean the end of life for such programs.
I suggest you remove deprecated methods when you gain something from the removal:
Removing deprecated methods just because they were deprecated for X months/years or because you're releasing a new version amounts to arbitrarily harming compatibility with no good reason.
First you should consider whether you want deprecated or obsolete.
Deprecated should be used for methods that are in some way harmful: security, performance, incorrect results. You want to get rid of them relatively quickly, no more than 2 major version and gone by the 3rd. For significant enough problems, deprecated may be deleted in the next minor version.
Obsolete is for things that are less useful for some reason, for instance returns less information or doesn’t work as well, doesn’t include as many options and so forth. These can hang around indefinitely, but should at a minimum be present in the next major version.
The answer depends on what sort of service you are giving to your customers.
On one end of the extreme, there are mistakes in Windows.h from the Win 3.1 era that propagated for two decades because Microsoft believed very strongly in backwards compatibility.
On the other end of the spectrum, many web-apps remove features without even providing a deprecation warning.
How much your clients are paying for your software often matters, as does their line of work. Research scientists are typically more willing to accept deprecation as part of the march of progress than, say, bankers or the FAA.
I worked for a company developing software for internal use. I supported many groups over the years. One group had a "never remove any feature" mentality. They needed the ability to go back to files 5-10 years ago and do analysis on them on timescales too fast to get developers to put features back in. One group's attitude was "make sure all the deprecations are in the patch notes, so we can find them later." In the middle, we had one group whose rule was "Features must be deprecated for at least 1 version with a printed warning if they are used before removing them." That group had a test suite that covered the features they needed. Whenever we released a new version, they quick ran their test suite against it to see if any of the deprecations gave them trouble.
I am maintaining a public API and have to deprecate a method.
Why do you need to do this? Is it because there’s a new shiny way to do things, so the old method is now discouraged, but still works fine? Or does the old method actually need to go because things have fundamentally changed?
If the old method isn’t causing any actual problems, and can stick around, then it may as well. If ain’t broke, don’t fix it. Do you really need to remove it? Maybe mark it as obsolete, and include a note in the documentation that another method might be more efficient, or whatever, but it’s probably fine to leave it in place.
If the old method really does need to go, because it’s causing you maintenance headaches, or because it simply no longer makes any sense due to other changes, then monitor its usage and communicate the deprecation clearly to clients. Give them a clear date after which the method will be removed. (Ideally, don’t actually remove it immediately on this date: wait until no one is still using it before actually removing it. It may need to go sooner, if it’s really causing problems, but at least wait for the usage to drop a little.)
If the old method is causing security problems, you may need to move faster than that, possibly even removing it without warning, but you should document this change somewhere very visible, and also return sensible messages to clients which attempt to use the old method.
(The second two bullet points are well covered in other answers, but I think the first one is new.)
For a public project, only remove it if and only if you need to.
When you do unnecessary API removal, you're costing money for companies and contractors in such a way that you can't even calculate due to costly churn.
Want companies and independent programmers to stop using your project? Break their stuff enough times when you're not essential and you'll be in that boat in no time.
deprecation != eventual_removal. If an API is dangerous, you remove it. If it's just old, leave it and document its replacement.