mirror of
https://github.com/twirl/The-API-Book.git
synced 2025-05-31 22:09:37 +02:00
clarifications & style fixes
This commit is contained in:
parent
e4b7c39def
commit
3094f7b2e0
@ -6,11 +6,11 @@ Backwards compatibility is a feature of the entire API system to be stable in ti
|
||||
|
||||
1. What does “functionally correctly” mean?
|
||||
|
||||
It means that the code continues to serve its function, e.g. solve some users' problems. It doesn't mean it continues working indistinguishably: for example, if you're maintaining a UI library, changing functionally insignificant design details like shadow depth or border stoke type is backwards compatible, whereas changing visual components size is not.
|
||||
It means that the code continues to serve its function, e.g. to solve some users' problems. It doesn't mean it continues working indistinguishably from the previous version: for example, if you're maintaining a UI library, changing functionally insignificant design details like shadow depth or border stroke type is backwards compatible, whereas changing the sizes of the visual components is not.
|
||||
|
||||
2. What does “a long period of time” mean?
|
||||
|
||||
From our point of view, the backwards compatibility maintenance period should be reconciled with the subject area application lifetime. Platform LTS periods are decent guidance in most cases. Since apps will be rewritten anyway when the platform maintenance period ends, it is reasonable to expect developers to move to the new API version also. In mainstream subject areas (e.g. desktop and mobile operating systems) this period lasts several years.
|
||||
From our point of view, the backwards compatibility maintenance period should be reconciled with the typical lifetime of appliactions in the subject area. Platform LTS periods are decent guidance in most cases. Since apps will be rewritten anyway when the platform maintenance period ends, it is reasonable to expect developers to move to the new API version as well. In mainstream subject areas (e.g. desktop and mobile operating systems) this period lasts several years.
|
||||
|
||||
From the definition becomes obvious why backwards compatibility needs to be maintained (including taking necessary measures at the API design stage). An outage, full or partial, caused by the API vendor, is an extremely uncomfortable situation for every developer, if not a disaster — especially if they pay money for the API usage.
|
||||
|
||||
@ -18,39 +18,39 @@ But let's take a look at the problem from another angle: why the maintaining bac
|
||||
|
||||
We could say the *we break backwards compatibility to introduce new features to the API*. But that would be deceiving: new features are called *“new”* just because they cannot affect existing implementations which are not using them. We must admit there are several associated problems, which lead to the aspiration to rewrite *our* code, the code of the API itself, and ship a new major version:
|
||||
|
||||
* the code eventually becomes outdated; making changes, even introducing totally new functionality, is impractical;
|
||||
* the code eventually becomes outdated; making changes, even introducing totally new functionality, becomes impractical;
|
||||
|
||||
* the old interfaces aren't suited to encompass new features; we would love to extend existing entities with new properties, but simply couldn't;
|
||||
* the old interfaces aren't suited to encompass new features; we would love to extend existing entities with new properties, but we simply couldn't;
|
||||
|
||||
* finally, with years passing since the initial release, we understood more about the subject area and API usage best practices, and we would implement many things differently.
|
||||
* finally, with years passing since the initial release, we have understood more about the subject area and API usage best practices, and we would implement many things differently.
|
||||
|
||||
These arguments could be summarized frankly as “the API developers don't want to support the old code.” But this explanation is still incomplete: even if you're not going to rewrite the API code to add new functionality, or you're not going to add it at all, you still have to ship new API versions, minor and major alike.
|
||||
These arguments could be summarized frankly as “the API vendors don't want to support the old code.” But this explanation is still incomplete: even if you're not going to rewrite the API code to add new functionality, or you're not going to add it at all, you still have to ship new API versions, minor and major alike.
|
||||
|
||||
**NB**: in this chapter, we don't make any difference between minor versions and patches: “minor version” means any backwards-compatible API release.
|
||||
|
||||
Let us remind that [an API is a bridge]((https://twirl.github.io/The-API-Book/docs/API.en.html#chapter-2)), a meaning of connecting different programmable contexts. No matter how strong our desire to keep the bridge intact is, our capabilities are limited: we could lock the bridge, but we cannot command the rifts and the canyon itself. That's the source of the problems: we can't guarantee that *our own* code won't change, so at some point, we will have to ask the clients to change *their* code.
|
||||
Let us remind that [an API is a bridge]((https://twirl.github.io/The-API-Book/docs/API.en.html#chapter-2)), a meaning of connecting different programmable contexts. No matter how strong our desire to keep the bridge intact is, our capabilities are limited: we could lock the bridge, but we cannot command the rifts and the canyon itself. That's the source of the problems: we can't guarantee that *our own* code won't change. So at some point, we will have to ask the clients to rewrite *their* code.
|
||||
|
||||
Apart from our aspirations to change the API architecture, three other tectonic processes are happening at the same time: user agents, subject areas, and underlying platforms' erosion.
|
||||
Apart from our aspirations to change the API architecture, three other tectonic processes are happening at the same time: user agents, subject areas, and underlying platforms erosion.
|
||||
|
||||
#### Consumer applications fragmentation
|
||||
|
||||
When you shipped the very first API version, and the first clients started to use it, the situation was perfect. There was only one version, and all clients were using just it. When this perfection ends, two scenarios are possible.
|
||||
When you shipped the very first API version, and the first clients started to use it, the situation was perfect. There was only one version, and all clients were using only it. When this perfection ends, two scenarios are possible.
|
||||
|
||||
1. If the platform allows for fetching code on-demand as the good old Web does, and you weren't too lazy to implement that code-on-demand feature (in a form of a platform SDK — for example, JS API), then the evolution of your API is more or less under your control. Maintaining backwards compatibility effectively means keeping *the client library* backwards-compatible. As for client-server interaction, you're free.
|
||||
|
||||
It doesn't mean that you can't break backwards compatibility. You still can make a mess with cache-control headers or just overlook a bug in the code. Besides, even code-on-demand systems don't get updated instantly. The author of this book faced the situation when users were deliberately keeping a browser tab open *for weeks* to get rid of updates. But still, you usually don't have to support more than two API versions — the last one and the penultimate one. Furthermore, you may try to rewrite the previous major version of the library, implementing it on top of the actual API version.
|
||||
|
||||
2. If the code-on-demand feature isn't supported or is prohibited by the platform, as in modern mobile operating systems, then the situation becomes more severe. Each client effectively borrows a snapshot of the code, working with your API, frozen at the moment of compilation. Client application updates are scattered over time at much more extent than Web application updates. The most painful thing is that *some clients will never be up to date*, because of one of the three reasons:
|
||||
2. If the code-on-demand feature isn't supported or is prohibited by the platform, as in modern mobile operating systems, then the situation becomes more severe. Each client effectively borrows a snapshot of the code working with your API, frozen at the moment of compilation. Client application updates are scattered over time at much more extent than Web application updates. The most painful thing is that *some clients will never be up to date*, because of one of the three reasons:
|
||||
|
||||
* developers simply don't want to update the app, e.g. its development stopped;
|
||||
* users don't want to get updates (sometimes because users think that developers “spoiled” the app in new versions);
|
||||
* users can't get updates because their devices are no longer supported.
|
||||
|
||||
In modern times these three categories combined could easily constitute tens of per cent of auditory. It implies that cutting the support of any API version might be remarkable — especially if developers' apps continue supporting a more broad spectrum of platforms than the API does.
|
||||
In modern times these three categories combined could easily constitute tens of per cent of auditory. It implies that cutting the support of any API version might be a nightmare experience — especially if developers' apps continue supporting a more broad spectrum of platforms than the API does.
|
||||
|
||||
You could have never issued any SDK, providing just the server-side API, for example in a form of HTTP endpoints. You might think, given your API is less competitive on the market because of a lack of SDKs, that the backwards compatibility problem is mitigated. That's not true: if you don't provide an SDK, then developers will either adopt an unofficial one (if someone bothers to make it) or just write a framework themselves — independently. “Your framework — your problems” strategy, fortunately or not, works badly: if developers write poor quality code upon your API, then your API is of poor quality itself. Definitely in the view of developers, possibly in the view of end-users, if the API performance within the app is visible to them.
|
||||
|
||||
Certainly, if you provide a stateless API that doesn't require client SDKs (or they might be auto-generated from the spec), those problems will be much less noticeable, but not fully avoidable, unless you never issue any new API version. If you do, you will still have to deal with some fragmentation of users by API and SDK versions.
|
||||
You could have never issued any SDK, providing just the server-side API, for example in a form of HTTP endpoints. You might think that the backwards compatibility problem is mitigated (by making your API is less competitive on the market because of a lack of SDKs). That's not true: if you don't provide an SDK, then developers will either adopt an unofficial one (if someone bothered to make it) or just write a framework themselves — independently. “Your framework — your problems” strategy, fortunately or not, works badly: if developers write poor quality code upon your API, then your API is of poor quality itself. Definitely in the view of developers, possibly in the view of end-users, if the API performance within the app is visible to them.
|
||||
|
||||
Certainly, if you provide a stateless API that doesn't require client SDKs (or they might be auto-generated from the spec), those problems will be much less noticeable, but not fully avoidable unless you never issue any new API version. If you do, you will still have to deal with some fragmentation of users by API and SDK versions.
|
||||
|
||||
#### Subject area evolution
|
||||
|
||||
@ -60,49 +60,49 @@ The other side of the canyon is the underlying functionality you're exposing via
|
||||
* older functionality shuts down;
|
||||
* interfaces change.
|
||||
|
||||
As usual, the API provides an abstraction to a much more granular subject area. In the case of our [coffee machine API example](https://twirl.github.io/The-API-Book/docs/API.en.html#chapter-7) one might reasonably expect new models to pop up, which are to be supported by the platform. New models tend to provide new APIs, and it's hard to guarantee they might be adopted while preserving the same high-level API. And anyway, the code needs to be altered, which might lead to incompatibility, albeit unintentional.
|
||||
As usual, the API provides an abstraction to a much more granular subject area. In the case of our coffee machine API example, one might reasonably expect new machine models to pop up, which are to be supported by the platform. New models tend to provide new APIs, and it's hard to guarantee they might be adopted while preserving the same high-level API. And anyway, the code needs to be altered, which might lead to incompatibility, albeit unintentional.
|
||||
|
||||
Let us also stress that low-level API vendors are not always as resolute regarding maintaining backwards compatibility for their APIs (actually, any software they provide) as (we hope so) you are. You should be warned that keeping your API in an operational state, e.g. writing and supporting facades to the shifting subject area landscape, will be your problem, and rather a sudden one.
|
||||
Let us also stress that vendors of low-level API are not always as resolute regarding maintaining backwards compatibility for their APIs (actually, any software they provide) as (we hope so) you are. You should be warned that keeping your API in an operational state, e.g. writing and supporting facades to the shifting subject area landscape, will be a problem of yours, and sometimes rather a sudden one.
|
||||
|
||||
#### Platform drift
|
||||
|
||||
Finally, there is a third side to a story — the “canyon” you're crossing over with a bridge of your API. Developers write code that is executed in some environment you can't control, and it's evolving. New versions of operating systems, browsers, protocols, and programming language SDKs emerge. New standards are being developed, new arrangements made, some of them being backwards-incompatible, and nothing could be done about that.
|
||||
|
||||
Older platform versions lead to fragmentation just like older app versions do, because developers (including the API developers) are struggling with supporting older platforms, and users are struggling with platform updates — and often can't update at all, since newer platform versions require newer devices.
|
||||
Older platform versions lead to fragmentation just like older app versions do, because developers (including the API developers) are struggling with supporting older platforms, and users are struggling with platform updates — and often can't get updated at all, since newer platform versions require newer devices.
|
||||
|
||||
The nastiest thing here is that not only does incremental progress in a form of new platforms and protocols demand changing the API, but also does vulgar fashion. Several years ago realistic 3d icons were popular, but since then the public taste changed in a favor of flat and abstract ones. UI components developers had to follow the fashion, rebuilding their libraries, either shipping new icons or replacing old ones. Similarly, right now “night mode” support is introduced everywhere, demanding changes in a broad range of APIs.
|
||||
The nastiest thing here is that not only does incremental progress in a form of new platforms and protocols demand changing the API, but also does a vulgar fashion. Several years ago realistic 3d icons were popular, but since then the public taste changed in a favor of flat and abstract ones. UI components developers had to follow the fashion, rebuilding their libraries, either shipping new icons or replacing the old ones. Similarly, right now the “night mode” feature is introduced everywhere, demanding changes in a broad range of APIs.
|
||||
|
||||
#### Backwards compatibility policy
|
||||
|
||||
To summarize the above:
|
||||
* you will have to deploy new API versions because of apps, platforms, and subject area evolution; different areas are evolving at a different pace, but never stop doing so;
|
||||
* you will have to deploy new API versions because of apps, platforms, and subject areas evolution; different areas are evolving at a different pace, but never stop doing so;
|
||||
* that will lead to fragmenting the API versions usage over different platforms and apps;
|
||||
* you have to make decisions critically important to your API's sustainability in the customers' view.
|
||||
* you have to make decisions that greatly affect how sustainable your API is in your customers' view.
|
||||
|
||||
Let's briefly describe these decisions and the key factors for making them.
|
||||
|
||||
1. How often new major API versions should be developed?
|
||||
1. How often new major API versions should be released?
|
||||
|
||||
That's primarily a *product* question. A new major API version is to be released when the critical mass of functionality is reached — a critical mass of features that couldn't be introduced in the previous API versions, or introducing them is too expensive. In stable markets, such a situation occurs once in several years, usually. In emerging markets, new API major versions might be shipped more frequently, only depending on your capabilities of supporting the zoo of previous versions. However, we should note that deploying a new version before the previous one was stabilized (which commonly takes from several months up to a year) is always a troubling sign to developers, meaning they're risking dealing with the unfinished platform glitches permanently.
|
||||
That's primarily a *product* question. A new major API version is to be released when the critical mass of functionality is reached — a critical mass of features that couldn't be introduced in the previous API versions, or introducing them is too expensive. In stable markets, such a situation occurs once in several years, usually. In emerging markets, new major API versions might be shipped more frequently, only depending on your ability of supporting the zoo of the previous versions. However, we should note that deploying a new version before the previous one was stabilized (which commonly takes from several months up to a year) is always a troubling sign to developers meaning they're risking dealing with the platform glitches permanently.
|
||||
|
||||
2. How many *major* versions should be supported at a time?
|
||||
|
||||
As for major versions, we gave *theoretical* advice earlier: ideally, the major API version lifecycle should be a bit longer than the platform's one. In stable niches like desktop operating systems, it constitutes 5 to 10 years. In new and emerging ones, it is less but still measured in years. *Practically* speaking you should look at the size of the auditory which continues using older versions.
|
||||
*Theoretically*, all of them. *Practically*, you should look at the size of the auditory which continues using older versions, and develop some guidance on when the support ends.
|
||||
|
||||
3. How many *minor* versions (within one major version) should be supported at a time?
|
||||
|
||||
As for minor versions, there are two options:
|
||||
|
||||
* if you provide server-side APIs and compiled SDKs only, you may basically do not expose minor versions at all, just the actual one: the server-side API is totally within your control, and you may fix any problem efficiently;
|
||||
* if you provide code-on-demand SDKs, it is considered a good form to provide an access to previous minor versions of SDK for a period of time sufficient enough for developers to test their application and fix some issues if necessary. Since full rewriting isn't necessary, it's fine to align with apps release cycle duration in your industry, which is usually several months in worst cases.
|
||||
* if you provide server-side APIs and compiled SDKs only, you may basically do not expose minor versions at all (see below); however, at some maturity stage providing at least two latest versions becomes a must.
|
||||
* if you provide code-on-demand SDKs, it is considered a good form to provide an access to previous minor versions of SDK for a period of time sufficient enough for developers to test their applicationы and fix issues if necessary. Since minor changes do not require rewriting large portions of code, it's fine to align the lifecycle of a minor version with app release cycle duration in your industry, which is usually several months in worst cases.
|
||||
|
||||
#### Simultaneous access to several API versions
|
||||
|
||||
In modern professional software development, especially if we talk about internal APIs, a new API version usually fully replaces the previous one. If some problems are found, it might be rolled back (by releasing the previous version), but the two builds never co-exist. However, in the case of public APIs, the more the number of partner integrations is, the more dangerous this approach becomes.
|
||||
|
||||
Indeed, with the growth of the number of users, the “rollback the API version in case of problems” paradigm becomes increasingly destructive. To a partner, the optimal solution is rigidly referencing the specific API version — the one that had been tested (ideally, at the same time having the API vendor somehow seamlessly fixing security issues and making their software compliant with newly introduced legislation).
|
||||
Indeed, with the growth of the number of users, the “rollback the API version in case of problems” paradigm becomes increasingly destructive. To a partner, the optimal solution is rigidly referencing the specific API version — the one that had been tested (ideally, at the same time having the API vendor somehow seamlessly fixing security concerns and making their software compliant with newly introduced legislation).
|
||||
|
||||
**NB**. From the same considerations, providing beta (or maybe even alpha) versions of the popular APIs becomes more and more desirable as well, to make partners test the upcoming version and address the possible issues in advance.
|
||||
**NB**. From the same considerations, providing beta (or maybe even alpha) versions of the popular APIs becomes more and more desirable as well, to make partners test the upcoming versions and address the possible issues in advance.
|
||||
|
||||
The important (and undeniable) advantage of the *semver* system is that it provides the proper version granularity:
|
||||
|
||||
|
@ -87,13 +87,13 @@
|
||||
|
||||
2. Какое количество *мажорных* версий поддерживать одновременно.
|
||||
|
||||
Что касается мажорных версий, то *теоретический* ответ мы дали выше: в идеальной ситуации жизненный цикл мажорной версии должен быть чуть длиннее жизненного цикла платформы. Для стабильных ниш типа десктопных операционных систем это порядка 5-10 лет, для новых и динамически развивающихся — меньше, но всё равно измеряется в годах. *Практически* следует смотреть на долю потребителей, реально продолжающих пользоваться версией.
|
||||
*Теоретически*, все когда-либо выпущенные. *Практически* следует смотреть на долю потребителей, реально продолжающих пользоваться версией, и выработать какие-то правила, когда прекращать поддержку старой версии.
|
||||
|
||||
3. Какое количество *минорных* версий (в рамках одной мажорной) поддерживать одновременно.
|
||||
|
||||
Для минорных версий возможны два варианта:
|
||||
|
||||
* если вы предоставляете только серверный API и компилируемые SDK, вы можете в принципе не поддерживать никакие минорные версии API, помимо актуальной: серверный API находится полностью под вашим контролем, и вы можете оперативно исправить любые проблемы с логикой;
|
||||
* если вы предоставляете только серверный API и компилируемые SDK, вы можете в принципе не поддерживать никакие минорные версии API, помимо актуальной (см. нижк); однако, на определённом этапе развития популярных API становится хорошим тоном поддерживать по крайней мере две последние версии;
|
||||
* если вы предоставляете code-on-demand SDK, то вот здесь хорошим тоном является поддержка предыдущих минорных версий SDK в работающем состоянии на срок, достаточный для того, чтобы разработчики могли протестировать своё приложение с новой версией и внести какие-то правки по необходимости. Так как полностью переписывать приложения при этом не надо, разумно ориентироваться на длину релизных циклов в вашей индустрии, обычно это несколько месяцев в худшем случае.
|
||||
|
||||
#### Одновременный доступ к нескольким минорным версиям API
|
||||
|
Loading…
x
Reference in New Issue
Block a user