eiffel-community/eiffel-intelligence

Version handle the API

Opened this issue ยท 24 comments

Description

Introduce version handling of the API

Also, see #288 in the frontend

Motivation

By version handling, the API users can upgrade EI without having to change their code. The user can switch to the new API when they have the possibility.

Exemplification

Here you can read briefly about API versioning:
https://restfulapi.net/versioning/

The most common way is to append /v1 at the root path.

Suggested way forward:
We will keep supporting the old API (available in EI 2.x instances) and the new API (available from EI 3.x instances). But we will denote the old API as deprecated already in this implementation - to encourage users to migrate/new users to use the latest API.

We will not support a use case where the user accesses the API without any specified version (no default should exist). Users will be forced to always explicitly specify which version of the API they want to access.

Example:
Allowed:
www.eiffel-intelligence/v1/subscriptions
www.eiffel-intelligence/v2/subscriptions

Not allowed:
www.eiffel-intelligence/subscriptions

This implementation will be included in a future 4.0.0 release (because it will not be backwards compatible).

Deprecation strategies:
If and when we release a new major release of the API (a v3 API) we will remove support for the oldest API (v1) to only keep support for 2 API versions at the same time.

Latest API version ---> v2/
Deprecated API version ---> v1/
When EI with API version v3/ is released:

Latest API version ---> v3/
Deprecated API version ---> v2/
Deprecated API version v1/ ---> removed

Benefits

By version handling the API, it will be backward compatible.
For future users it will become easier to migrate between API versions, and they can decide when they feel ready to switch to a higher version of the API.

Possible Drawbacks

The planned implementation will mean a breaking change, with current users being forced to explicitly specify a version in the url to Eiffel Intelligence, whenever they want to access the API.
This will have to be included in a 4.0.0 release.

Is the current API (from 3.0.0 release) going to be the default and v1 of the API?
And any changes made from here on out should be backwards compatible, and if they're not they should be a v2?

I'd like this to be a backwards-compatible change to 3.0.0 release. (Since we've already made breaking changes between 2.x and 3.x release) Meaning that this current API will be the default if users don't specify any version in the uri.

http://eiffel-intelligence/subscriptions and http://eiffel-intelligence/v1/subscriptions should point to the same default version of the API.

In the future, if users want another version than default they include it in the uri, e.g. http://eiffel-intelligence/v2/subscriptions etc

This is just my opinion but when a decision is taken, I'd like it documented here to future reference.

I noticed the possibility of grouping different API's with Springfox implementation of Swagger. I don't know if this is somehting we want, but whoever looks into this issue can perhaps take a look and see if it's useful. Read more here: http://springfox.github.io/springfox/docs/2.6.1/#swagger-group

Sounds as good solution to versioning the API.
I have seen issues that users use entrypoints that is available on root url and when a new version of application with rest entrypoint changes is deployed, then users is impacted and the users application functionality stop working.

My suggestion:

  1. Don't have any entrypoints on the root url. User should specify a specific API version from the start, so the users application is not impacted when a new version is deployed with new API changes(that introduces a new API version).
  2. EI 2.X RestApi entrypoints should be placed under "v1/" root url context-path.
  3. EI 3.X RestApi entrypoints should be placed under "v2/" root url context-path.
  4. EI application root-url without API version should redirect to Swagger page.

By implementing according these 4 implementation suggestions, we will avoid that users will be impacted by RestApi changes when new EI versions is deployed and users applications can decide when its suitable to switch to new API version.

How should we deprecate entrypoints? How long or many releases should we keep deprecated entrypoints versions?

We could have a rule to only keep 2 deprecated API versions:
Example:
v4/
v3/ (deprecated)
v2/ (deprecated)
v1/ (deprecated) -> removed when version /v4 is released.

Next version:
v5/
v4/ (deprecated)
v3/ (deprecated)
v2/ (deprecated) -> removed when version /v5 is released.

What do you think? or should only one deprecated version be kept?

Yeah, if I understood correctly, If EI 2.X RestApi entrypoints should be placed under "v1/" root url context-path and EI 3.X RestApi entrypoints should be placed under "v2/" root url context-path. then every entrypoint and its functionality have to be added to every future versions without any change. So instead we have approached through @mapping()
EX: @GetMapping(value = {"/v1","/v2"}).
Swagger grouping is done to the respective entrypoints or its required functionality.
So that mapping could be done to its respective entrypoints if there is a change in version.

Yes, user application need to have version specified to keep the backward compatibility and avoid user to be impacted by API changes.

overview:

According to the version handling restAPI Endpoints :

Version handling is to continue using the existing REST API and migrate their applications to the newer API when they are ready.
-> Identified restAPI endpoints between the versions.
-> Identified changes between the versions and covered the user scenarios as follows:

  • Add new endpoints
  • Delete endpoints
  • Endpoint name change
  • Endpoint request params(Header, Path, Query string Request body parameters) change.
  • Endpoint functionality change
  • Endpoint response changes.
    so based on the change between the versions by swagger group concept and map the versions using @mapping(). Ex: @GetMapping(value = {"/v1","/v2"}) to its respective changed functionality of the version, where old version kept in parallel.

Considered latest as the default version ( no URL change for the user ).
EX: If /v1 has changes in the endpoint and changes have been released in /v2 version then v2 will be considered as the default version because its the latest one.
User need the change the urls if requires old versions entrypoints.

Latest API version link to api version "v2/" has very bad impact on the users, since user will get API version "v3/" when new EI version is deployed without a chance for the user to adapt to the new API version, and things stops working for the user.
Due to this issue we should not have any entrypoints on root url and User should pick a API version "v1/" or "/v2" to use, so when API version "v3/" is deployed, user will not be impacted. User can continue use previous API versions as user did with previous EI versions.
User can then adapt to the new API version when user find a suitable time for that.

Yes as per our proposal if user picks a API version "v1/" or "v2/" to use so when the new API "v3/" is deployed user will not be impacted. User can continue use previous API versions as user did with previous EI versions. User can then adapt or choose to the new API version when user find a suitable time for that. As in parallel we are maintaining previous versions.

WHat do you mean with previous versions? EI versions or the new API version structures versions?

So I interpret this as: we will not support a use case where the user accesses the API without any specified version (no default should exist). Users will be forced to always explicitly specify which version of the API they want to access - is this correct?

Example:

Allowed:
www.eiffel-intelligence/v1/subscriptions
www.eiffel-intelligence/v2/subscriptions

Not allowed:
www.eiffel-intelligence/subscriptions

I prefer it this way, but I just want to make sure we are in agreement on this. @zrddnvt @tobiasake

Yes,, thats my opinion and what also has been discussed in other applications developments I am part of.

Just FYI, when we implement this, we will break backwards compatibility yet again, since we will force existing users to start using an explicit version when they use EI REST API. We will have to make this change part of a 4.0 release of Eiffel Intelligence which will support 2 API versions (old one in 2.x and new in 3.x)

So users on a 3.x EI will have to adjust the url to include a /v2 when they access the API, when they migrate to a 4.x EI.
And users currently on a 2.x version of EI will have to include a /v1 if they wish to continue using the old API, or upgrade to the new API (and adjusting their HTTP requests according to the v2 API changes) when they migrate to a 4.x EI version.

We will break backward compatible whatever option we choose,, so lets do it right from the beginning.
Yes, this change need to be a EI 4.x release.

Should we also add the "deprecated" flag onto the old API with this implementation? We will still support the old API for some time. But to make users aware that they should migrate to the new API. And the old API will be kept until a new MAJOR release of Eiffel Intelligence (i.e. 5.x)?

WHat do you mean with previous versions? EI versions or the new API version structures versions?

EI versions.

So I interpret this as: we will not support a use case where the user accesses the API without any specified version (no default should exist). Users will be forced to always explicitly specify which version of the API they want to access - is this correct?

Example:

Allowed:
www.eiffel-intelligence/v1/subscriptions
www.eiffel-intelligence/v2/subscriptions

Not allowed:
www.eiffel-intelligence/subscriptions

I prefer it this way, but I just want to make sure we are in agreement on this. @zrddnvt @tobiasake

okay, we actually considered latest as default so that, if user is not specifying any version explicitly.
Example:
www.eiffel-intelligence/subscriptions/v1 --- EI2.x version rest API
www.eiffel-intelligence/subscriptions----- EI3.x version rest API

If this is the approach required we will do that.
www.eiffel-intelligence/v1/subscriptions
www.eiffel-intelligence/v2/subscriptions

I don't think we should keep root url entrypoints,, because then we get another release with more new users that have same issue, where API is changed and user is directly impacted. My suggestion is to remove the root url entrypoints directly and let/force user from start/early as possible use the versioned entrypoints.

Regarding deprecated, I added a suggestion regarding that earlier in this thread.

So I interpret this as: we will not support a use case where the user accesses the API without any specified version (no default should exist). Users will be forced to always explicitly specify which version of the API they want to access - is this correct?
Example:
Allowed:
www.eiffel-intelligence/v1/subscriptions
www.eiffel-intelligence/v2/subscriptions
Not allowed:
www.eiffel-intelligence/subscriptions
I prefer it this way, but I just want to make sure we are in agreement on this. @zrddnvt @tobiasake

okay, we actually considered latest as default so that, if user is not specifying any version explicitly.
Example:
www.eiffel-intelligence/subscriptions/v1 --- EI2.x version rest API
www.eiffel-intelligence/subscriptions----- EI3.x version rest API

If this is the approach required we will do that.
www.eiffel-intelligence/v1/subscriptions
www.eiffel-intelligence/v2/subscriptions

Exactly like @tobiasake mentioned above. Let's imagine if we have the following alternatives to the API:

www.eiffel-intelligence/v1/subscriptions (old API)
www.eiffel-intelligence/v2/subscriptions (latest API)
www.eiffel-intelligence/subscriptions (default linking to latest version)

When we add a new API version: www.eiffel-intelligence/v3/subscriptions
this will be the latest, and users currently using www.eiffel-intelligence/subscriptions
without any version specified will notice things start breaking when they upgrade to new version of EI and wonder why. This is because the default API (without explicit version) will point to a NEW latest.

This pattern will continue happening if we allow users to access the API without a version. And that is why I do not like to have a default approach. I hope you understand why we are against this suggestion. And please consider to not allow any default url.

How should we deprecate entrypoints? How long or many releases should we keep deprecated entrypoints versions?

We could have a rule to only keep 2 deprecated API versions:
Example:
v4/
v3/ (deprecated)
v2/ (deprecated)
v1/ (deprecated) -> removed when version /v4 is released.

Next version:
v5/
v4/ (deprecated)
v3/ (deprecated)
v2/ (deprecated) -> removed when version /v5 is released.

What do you think? or should only one deprecated version be kept?

If we wil lsupport 2 deprecated versions of the API this means we will support in total 3 API versions. How much more complexity does this give than only supporting 2 versions? I'm not sure what I think actually.

It was my first suggestion, I have not strong opinion about that.
We can have only 2 API version

  • Current API version v2/
  • Deprecated API version v1/

When EI with API version v3/ released:

  • Current API version v3/
  • Deprecated API version v2/
  • Deprecated API version v1/ -> removed

Is that a better suggestion?

It was my first suggestion, I have not strong opinion about that.
We can have only 2 API version

  • Current API version v2/
  • Deprecated API version v1/

When EI with API version v3/ released:

  • Current API version v3/
  • Deprecated API version v2/
  • Deprecated API version v1/ -> removed

Is that a better suggestion?

For me it would be OK.
I'd like to hear others opinion about this @zrddnvt @raja-maragani

It was my first suggestion, I have not strong opinion about that.
We can have only 2 API version

  • Current API version v2/
  • Deprecated API version v1/

When EI with API version v3/ released:

  • Current API version v3/
  • Deprecated API version v2/
  • Deprecated API version v1/ -> removed

Is that a better suggestion?

Yes, as per my opinion this could be better. (Y)

I updated the description of the issue with what we've discussed. Does it seem OK?