At the moment I'm implementing versioning for our REST API in our Rails application. Is there a way this can be implemented so you only define new functionality in new versions? Say for example:
I have a Users controller and a Products controller. Products has stayed the same between V1 and V2, but Users has changed. It would be nice if we could set it up so that if I call for V2 of Products, my application knows it doesn't exist and simply uses the most recent controller version instead (in this case, V1). This would allow for us to not create a whole new set of controllers for every version; we'd only create new controllers for the specific functionality that has changed.
Below is a snippet from our Routes.rb, and admittedly I have no idea how to tackle this problem. Any help would be greatly appreciated!
namespace :api do
scope module: :v1, constraints: ApiConstraints.new(version: 1) do
resources :users
resources :products
end
scope module: :v2, constraints: ApiConstraints.new(version: 2) do
resources :users
end
end
I've used the same strategy for sometime and recently changed approaches-and admittedly I'm biased because I'm also one of the authors of our new approach with VersionCake.
This approach is to only version our payloads or views, afterall views are the contract between the client and if there is a breaking contract change, then the version needs to change. In VersionCake, you can version your views like so:
app/views/products/show.v1.rabl
app/views/products/show.v2.rabl
app/views/users/show.v1.rabl
The specific feature that is important based on your question is that VersionCake will gracefully degrade to the latest supported version. Given the example above, a client requesting users/1.json
for version 2 will receive the payload for users/show.v1.rabl
.
All this being said, it would require adopting a new versioning approach, so it might not be the best answer, but I think it's an option worth considering.
Have you looked at Grape already?
What I have done over the API's I have built is, when something changes for all of them (like authentication) I just get them all to inherit from a specific versioned api controller, as in Api::V1::BaseController
and place the common behavior and controls in there.
Since changing the API usually also meant changing the representations, using a tool that generates the representations for your is also really important, there are many gems out there for this as:
This is what Grape is designed to do.
In addition, you have the option of mounting your API in your routes.rb file or mapping it in config.ru, bypassing the Rails stack and greatly improving the performance of the API.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With