-
Notifications
You must be signed in to change notification settings - Fork 8
Enforcing a minimum APP version
REST doesn’t provide for any specific versioning guidelines but the more commonly used approaches fall into three categories, URI versioning, custom request header or using the ‘accept’ header. The best option depends on your requirements. In the following guide we will explain how to implement versioning using a custom header.
The idea is to define a custom header (e.g Accept-version), which must be present in every request made to the API. In the header, the user sends the version of the APP that is being used. In the back, defined in an environment variable, is the version of the API required to operate.
When a request is made, before performing any action, the custom header is compared with the required version stored in the environment variable. If it meets the requirements, the action is continued, otherwise the corresponding error is rendered.
1. Define an environment variable where the minimum version required to operate with the API is stored. Example on Heroku:
2. Then in the back we must compare said variable with the header. I'm going to give an example of how we did it in one of our projects using a module defined in concerns:
In this case within the right_version?
method, we use the Gem::Version
class to compare the value stored in the environment
variable
with the custom header received. If the user is using a version lower than the minimum acceptable, an error is rendered and the flow does not
continue.
This class process string versions into comparable values. A version string should be a series of numbers separated by periods. Each part (digits separated by periods) is considered its own number. For instance, 3.10 sorts higher than 3.2 because ten is greater than two. The string can contain letters (only a to z are supported), if that so the version si considered a prerelease.
More info: https://docs.ruby-lang.org/en/2.6.0/Gem/Version.html
3. After defining the concern we make the include in the ApiController
so that it is executed before any action.