Skip to content
New issue

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

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

Already on GitHub? # to your account

Add versioned HTTP API #2381

Open
dborovcanin opened this issue Aug 12, 2024 · 5 comments
Open

Add versioned HTTP API #2381

dborovcanin opened this issue Aug 12, 2024 · 5 comments
Assignees

Comments

@dborovcanin
Copy link
Collaborator

Is your feature request related to a problem? Please describe.

As we approach 1.0, we should start thinking of versioning our API.

Describe the feature you are requesting, as well as the possible use case(s) for it.

While we will make the best effort to keep post-v1.0 API compatible, there is no guarantee that will be possible. For those reasons, we should add versioning to enable using old API and seamlessly switch to newer versions of Magistrala.

Indicate the importance of this feature to you.

Must-have

Anything else?

No response

@github-project-automation github-project-automation bot moved this to ⛏ Backlog in SuperMQ Aug 12, 2024
@felixgateru felixgateru moved this from ⛏ Backlog to 🚧 In Progress in SuperMQ Jan 27, 2025
@felixgateru
Copy link
Contributor

I have encountered the following methods of versioning the api.

  1. Header versioning - The version will be passed as a header in each request. We can implement chi middleware to extract the middleware version for further processing.
  2. Query parameter versioning - The version number will be a query parameter. This can be extracted by handler logic.
  3. URL versioning - the version number is in the url of the endpoint. This is naturally handled by chi routing.

In all the above we will require to maintain code for each version. The advantage and disadvantage being that we can maintain all the versions in parallel.

My recommendation would be for URL versioning, it seems more intuitive and user friendly. It would be easy to update documentation. Would be easier for proxying and caching.

@dborovcanin
Copy link
Collaborator Author

OK, let's go with URL path versioning. It is simple, explicit, and easy for developers to understand and implement, and also the most popular for those reasons. For the time being, let's just address the URL prefix. We will not move implementation under api/v1 package just yet, because we still have only v1 so grouping does not make sense now. However, the URL prefix is a must since it is a breaking change.

@felixgateru felixgateru moved this from 🚧 In Progress to 🩺 Review and testing in SuperMQ Jan 28, 2025
@dborovcanin
Copy link
Collaborator Author

Another point here is how the API version correlates to the code version? Do we keep separate modules/create wrapper packages, or determine API version from the version endpoint of the service? Should this be done on the deployment level (i.e. on ingress)? @felixgateru Please research this and write comments here.

@dborovcanin dborovcanin moved this from 🩺 Review and testing to 🛑 Blocked in SuperMQ Jan 29, 2025
@dborovcanin dborovcanin moved this from 🛑 Blocked to 🚧 In Progress in SuperMQ Jan 30, 2025
@dborovcanin
Copy link
Collaborator Author

@felixgateru Please take this one.

@felixgateru
Copy link
Contributor

felixgateru commented Jan 30, 2025

Code organization

With implementing the URL versioning, the code can be organized in the following ways:

  1. Seperate packages for the api and expanded service interface. The api packages will follow the following folder structure:
/api
	/v1
		/endpoints.go
		/transport.go
	/v2
		/endpoints.go
		/transport.go

Depending on how different the versions are, this would necessitate expansion of the service interface as well to include versioned methods. This would enable mainting older versions of methods and introduce new methods. There is the possibility of code duplication between versioned methods.
Shared logic can be stored in a common package.
This method may have the following advantages:

  • The codebase would remain straightforward and easy to maintain with parallel development.
  • Makes deprecating older versions simpler.

The biggest drawback would be code duplication even in the service.

  1. Creating wrapper packages and middleware for shared logic.
    There would be middleware to handle version specific operations and reduce code duplication. Similar to the current authorization middleware we have. This would reduce code duplication. This would however be logical for small changes where the underlying service logic does not have large differences. Depending on the scale of the difference there may no reason for an expanded service interface with versioned methods.

The biggest drawback would be major changes would require refactoring code used by all the versions.

  1. Versioning via Nginx or Proxy
    This would require maintaining seperate packages and possible a separate service.
    My biggest question with this if it is necessary given that all versions will run from the same service. I think this would be best utilized with different backend services.
    It can be used to direct unversioned traffic to a default version.

Links:

@arvindh123 arvindh123 moved this from 🚧 In Progress to 🩺 Review and testing in SuperMQ Feb 3, 2025
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
Status: 🩺 Review and testing
Development

No branches or pull requests

3 participants