Skip to content

Handle serializer namespacing more robustly #886

Open
@eprothro

Description

@eprothro

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:

  1. We want namespaced controllers to use namespaced serializers, without explicitly specifying a serializer or namespace in the controller
  2. 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:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions