Description
Continuing from #144 at the request of @joaomdmoura.
@MarkMurphy and others suggest automatically handling lookup context similar to ActionView. This solves two distinct issues that would provide a good solution to serializer versioning:
- We want namespaced controllers to use namespaced serializers, without explicitly specifying a serializer or namespace in the controller
- We want namespaced serializers to use namespaced serializers for association serialization, without explicitly specifying a serializer or namespace with the association
More info from Mark's proposal, copied:
If the get_serializer
method here functioned in the same manner as rails does template lookups for a controller's views, then versioning would be as easy as namespacing your controllers.
For example:
# app/controllers/api/v1/users_controller.rb
module API::V1
class UsersController < APIController
def show
@user = User.find(params[:id])
render json: @user
end
end
end
Based on the above controllers' namespace, AMS would look for a User serializer at the following locations in order of priority:
app/serializers/api/v1/user_serializer.rb
app/serializers/api/user_serializer.rb
app/serializers/user_serializer.rb
So when api version 2 comes around you'll have the following:
# app/controllers/api/v2/users_controller.rb
module API::V2
class UsersController < APIController
def show
@user = User.find(params[:id])
render json: @user
end
end
end
Based on the above controllers' namespace, AMS would look for a User serializer at the following locations in order of priority:
app/serializers/api/v2/user_serializer.rb
app/serializers/api/user_serializer.rb
app/serializers/user_serializer.rb
Routes would look something like this:
# config/routes.rb
constraints subdomain: 'api' do
namespace :api, path: nil, except: [:new, :edit], defaults: { format: 'json' } do
# API V1
constraints API::VersionConstraint.new(version: 1) do
scope module: 'v1' do
resources :users
end
end
# API V2
constraints API::VersionConstraint.new(version: 2, default: true) do
scope module: 'v2' do
resources :users
end
end
end
end
Reference: