Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Versioning discussion #187

Open
croissanne opened this issue May 20, 2021 · 5 comments
Open

Versioning discussion #187

croissanne opened this issue May 20, 2021 · 5 comments
Labels
question Further information is requested

Comments

@croissanne
Copy link
Member

croissanne commented May 20, 2021

We have to tackle this sooner rather than later, so I have a few points that warrant discussion:

semver

Clouddot uses semantic versioning. I say we do our very best to only make major version changes, just so we only have one way to increase a version.

each version has their own package

Because each version has it's own spec file, we need to pull the generated api and the handlers from the server package into their own packages. I propose having internal/v1, internal/v2, etc....

Handlers will be duplicated, but I think that's fine to keep maintainability.

shared code

We should try to keep utilities shared between these packages (the database, logger etc...) common as much as we can to avoid duplication. I think having the database common makes sense since any migration needs to be backwards compatible anyway.

The clouddot guidelines state to support old versions as long as is 'reasonably possible', and I think the moment we have to bend over backwards in these shared parts in order to keep an older version, we should drop that older version.

Versioned IB -> versioned composer (CO)

I'd like to start out with keeping the cloudapi client shared between versions, and try having all versions of IB work against a single version of CO. If this turns out to be very difficult, we'll have to start adding multiple versions to the cloudapi client.

@croissanne croissanne added the question Further information is requested label May 20, 2021
@teg
Copy link
Member

teg commented Jun 20, 2021

Over all I agree with your proposals.

We may need to consider if we need to support minor versions when we make additions to our API, if this is something that consumers of our API expect. Ideally we would not.

One wish, which I have no idea if is possible: would it be possible to use a semver aware framework which would allow us to have one implementation where endpoints were annotated appropriately, and making it appear as different versions was done at runtime?

@croissanne
Copy link
Member Author

croissanne commented Jun 21, 2021

Over all I agree with your proposals.

We may need to consider if we need to support minor versions when we make additions to our API, if this is something that consumers of our API expect. Ideally we would not.

So with minor versions I think we could just move the specs into a sub package (so internal/v1/specs/(v1.0/v1.1), and then upgrade any requests coming in on earlier endpoints to the latest version in middleware. Considering the limited changes you should make, this upgrading shouldn't be an issue. So you'd still have a single handler implementation between minor versions, and always use the latest one.

One wish, which I have no idea if is possible: would it be possible to use a semver aware framework which would allow us to have one implementation where endpoints were annotated appropriately, and making it appear as different versions was done at runtime?

This would be ideal but I honestly have no idea. I mean we could only implement the endpoint once, and then within the handler check what version was called and handle it differently depending.

@croissanne
Copy link
Member Author

So started a little on this: https://github.com/Gundersanne/image-builder/tree/move-common. This moves distribution and prometheus stuff to common, and then renames server to v1.

Within v1 we could have the current spec in the top level, and then older specs in subpackages (internal/v1/m0 for v1.0 if the current version is v1.1). Then we'd introduce a middleware which upgrades each v1.0 request to a v1.1 request where necessary.

The response is a bit more hairy though :/ Would it be bad to always return v1.1 (that is latest version) responses? Not sure if the response can change without upgrading a major version either (in which case it should be fine).

@teg
Copy link
Member

teg commented Jun 29, 2021

So v1.1 should be backwards compatible with v1.0, so worst case a client expecting v1.0 and getting v1.1 will get some additional stuff they can ignore... Not sure if that will be a problem or not though.

@croissanne
Copy link
Member Author

Exactly that's the idea here. So I think that's fine? I'll try to open a PR for this soon, that way we have a precedent at least!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants