On Wed, Feb 13, 2019 at 1:20 PM Gray, Jonathan <jonathan_g...@comcast.com> wrote: > > I'm +1 on keeping full API SemVer.
> On 2/13/19, 12:16 PM, "Robert Butts" <r...@apache.org> wrote: > > We would be abandoning Semantic Versioning. This is why I wanted to open this up for broader discussion within the community. It doesn't seem like the idea of full TO API SemVer was ever fully discussed and voted on (at least not to my knowledge), which is why I haven't been abiding by it myself or enforcing it upon other TO API devs either. If we're going to truly commit to SemVer with minor versions for TO API then we should fully understand the cost vs utility of doing so. Also, SemVer doesn't have to be an "all or nothing" thing, as we currently choose to ignore the "patch" version for the TO API. We could also choose to ignore the minor version and just focus on the most important aspect of SemVer which is not introducing backwards-incompatible changes in the same major version. Since it seems like we never truly committed to SemVer with minor versions for the TO API, traffic_ops_golang wasn't designed to easily support minor versions. So if we're going to truly commit to SemVer with minor versions for TO API, then that support has to be baked into traffic_ops_golang such that it's easy and maintainable to support tons of minor versions. If we keep heading down our current path we are going to be left with a giant mess. The only way I can get behind supporting the "minor version promise" is if we have a way to basically just tag fields as introduced in a specific API version, with just a single struct per resource and a single handler per major version of an endpoint. We should only require a single implementation of an endpoint per major version. If a custom JSON parser allows us to do that, then that's great. Without that, I don't think supporting the "minor version promise" is even a viable option. A lot of those scenarios around user confusion due to supporting just a major version are not really an issue as long as we set the expectations for the user. I.e.: - clients should request v1 - as the v1 API is enhanced in a backwards-compatible manner, clients will begin to see new fields in the server responses - if a client wants to modify a resource, they will typically do a GET on the resource, modify the resource, then do a PUT back to the server. - in the GET response, if the client sees new fields, they can expect to modify those fields and see it reflected on the server. - if the client does NOT see new fields, then they cannot add fields and expect to see that reflected on the server - null values in optional fields will be interpreted by the server as whatever the default for that optional field is. So if the default for new optional field "foo" is 5, then a client sending `"foo": null` will be interpreted by the server as `"foo": 5`, and `"foo": null` should never have a different meaning than `"foo": 5` on the server. The advantage of just supporting the "major version promise": - jives better with Go's lack of metaprogramming - no custom JSON parser in Go required - less general overhead in development - only have to worry about breaking changes - no worrying about which fields belong to which minor versions - no extra API testing to make sure fields introduced in API v1.N aren't returned to v1.N-1 clients - don't have to update every single client in the repo with the new minor version every time a minor version is incremented (since clients would just specify the major version) So, as a community, we need to weigh these options and decide whether or not we want to take the "major version only" route or the "major plus minor version" route. Personally, I prefer the "major version only" route because it means less code, less overhead, less coordination, and less things to potentially go wrong. However, if a relatively small custom JSON parser is all we really need to reasonably support the "minor version promise", then I can't say I'm completely against that route either (just that I wouldn't prefer it). - Rawlin