-1 There are a few reasons I disagree here.

First, I think you’ve correctly identified that using an un-version in the 
field is problematic.  However, I’d argue that it’s more than just having to 
move all the pieces of the release together in lockstep.  If at any point you 
really must move any component ahead of an official release and use that 
unversion, all bets are off when it comes to upgrade safety.  Additionally, it 
creates concerns around things like upgrade order, timing, and what’s available 
when to what midflight.  Today we test all our components as a monoversion, but 
we rely on the API version promise to carry things forward safely in any order 
theoretically.  API versioning isn’t just about the technical aspects of 
software compatibility but also as a language for communicating expectations 
and change.  If I’m developing using the unversion, I can’t express if my thing 
works with yours or not in addition to if it will work in concert with other 
pieces of the puzzle or after an upgrade. “This means certain upgrades … would 
have to be closely coordinated with Traffic Ops” is simplest when you can say 
“does the target software version support my current API version, or what 
common api/software version(s) do I need to get to first” like normal.  Having 
to define special release upgrade procedures or comparing changesets with each 
other, especially across teams/implementations, is error prone.

Second, as a developer of support software around ATC I already make this 
assumption that the latest version available is unstable without an unversion 
concept.  The reason I make that assumption is because whatever the latest is 
can still have modifications made to outside the rules of api versioning or 
simply just being more bugprone than something that’s not being as actively 
touched.  The driving force behind API changes is that our data model changes 
when we refactor or improve.  I’m unlikely to willfully upgrade api versions 
for api version’s sake unless I either need something newer, or I’m forced to 
for backward compatibility (carrot vs stick).  It’s not a perfect rule of thumb 
because we do sometimes break the API retroactively like with the move to 
strong typing or when removing perl before the 1.x api.  The removal of the 1.x 
API is showing how expensive it truly is to safely remove API versions, and 
that’s something to be weighed in addition to maintenance cost to the project 
for those versions.  I think the million-dollar question revolves more around 
how much/far back we are willing to support.  If it’s only one release at a 
time, that’s going to drive those 3rd party code maintenance costs up 
significantly higher as part of just doing business which will slow down 
deployments even if releases are moving faster.

Third, an unversion just sounds like an opportunity for two developers working 
on different things but the same struct or endpoint to conflict and not realize 
it.  Additionally, it puts the burden on somebody at release time to bless a 
snapshot of whatever is in there as stable or know how to bisect all of what’s 
happened since the last project release.

Lastly, if the debate around cutting releases somehow being dependent on API 
code being merged, I argue it’s around feature completeness/usefulness instead. 
 Merging half-baked features before they’re ready to avoid API versioning 
issues would be better solved using feature branches.

If maintaining multiple versions of our api is expensive, there are 
other<https://github.com/rob05c/apiver> solutions<https://elixir-lang.org/> 
that might be worth investigating to make it cheaper.  Also, if the 
accumulation is a problem, I’m fine with a standing deprecation of all versions 
in a release that aren’t api -1 or a previously supported release.  That still 
means they stick around a little bit, but they’d survive one major upgrade at 
least in case you are running ahead.

Jonathan G


P.S.  Related historical mailing list conversation references:

  *   Traffic Ops API Semantic 
Versioning<https://lists.apache.org/thread.html/1a42a2192a81fc4d76639ccd10761b6b73c31345a63715bb8aa86e4e%40%3Cdev.trafficcontrol.apache.org%3E>
  *   Traffic Ops API versioning 
issues<https://lists.apache.org/thread.html/504b33b9c7b037a3b17a44613b326e0bdefd191cb7e62c0aca9e9515%40%3Cdev.trafficcontrol.apache.org%3E>
  *   Traffic Ops Route Deprecation 
Strategy<https://lists.apache.org/thread.html/b857afc7b52e72b2e60ebb3eb594b6fa5dd0ed3c9af5a17b58ee4a99%40%3Cdev.trafficcontrol.apache.org%3E>
  *   Deprecate APIv2 and 
v3<https://lists.apache.org/thread.html/re98819293cc349e9387a335c7a63498fb24eb783c82a2e2bef81b87f%40%3Cdev.trafficcontrol.apache.org%3E>

From: Rawlin Peters <raw...@apache.org>
Date: Friday, August 27, 2021 at 3:19 PM
To: dev@trafficcontrol.apache.org <dev@trafficcontrol.apache.org>
Subject: [EXTERNAL] Proposal: stable vs unstable TO API versions
Hey folks,

I'd like to propose that we start moving towards a TO API development
model where we consider the latest major version of the API
"unstable," while the 2nd latest major version is considered "stable."
What that means is that we would be free to make breaking changes to
the "unstable" version, while the "stable" version would maintain
backwards-compatibility. Eventually, once we feel that the latest
version of the TO API has stabilized, we will declare it "stable" and
deprecate the old stable version.

I see multiple benefits to this:
1. reduce the number of major API versions developers need to support,
making it easier to add new features
2. developers can make incremental changes (breaking and non-breaking)
to the unstable API version in every release without having to
introduce new major or minor versions, making the resulting API much
better overall once it is stabilized
3. reduce the number of unnecessary client upgrades, where the API
version changed but none of the routes the client uses were actually
changed
4. clients that don't need the latest API features don't have to upgrade
5. helps us release more frequently, because we aren't slowed down by
adding unnecessary code for a new TO API major/minor version with
every release
6. gives us more flexibility in what features need to be completed
before we cut a release (because they'd be targeting the unstable API
anyways, we can cut a release without causing a bunch of re-work for
new features that missed the API version bus)

Alas, all good things come at a price. For clients that need to use
the unstable version of the TO API (like Traffic Portal), their
upgrades may need to be closely coordinated with the Traffic Ops
upgrade. For TP, this is nothing new, because it is generally always
upgraded at the same time as TO. However, for other components that
may want to use the unstable API (e.g. `t3c`), this means certain
upgrades (not all, mind you, only those where a route the component
uses is actually broken) would have to be closely coordinated with
Traffic Ops. That said, for `t3c` at least, moving forward with Cache
Config Snapshots 
(https://urldefense.com/v3/__https://github.com/apache/trafficcontrol/pull/4708__;!!CQl3mcHX2A!Xwir0ypT4QqWermATCvTxSuv_hmAUW_lpc3T9a_ZdYeONDiveF0DqFudVmu_Sl4brueC$
 )
would greatly alleviate that concern, since the snapshot route would
be kept backwards-compatible.

Please let me know what you think of this proposal. If we can come to
a consensus on this, we may be able to declare TO API 3.0 "stable" and
4.0 "unstable," meaning we can avoid a potential 5.0 API version in
whatever release comes after ATC 6.0.

- Rawlin

Reply via email to