Skip to content

JSONAPI :: Create a Singleton Resource Profile

ngouy edited this page Jul 20, 2020 · 9 revisions

A singleton resource is a api url call that will always lead to only one resource. A real world use case would be "GET /profile" and "PATCH /profile" which (respectively) would get the profile record of the current user and update the record of the current record.

As mentioned in the documentation in the routes section, you need a singular resource route without an id:

config/routes.rb:

    jsonapi_resource :profile

You need to record the current logged in user via a context method on one of your controllers or across all controllers using ApplicationController:

    def context 
      { user: current_user } 
    end
  • v 0.8: you need to override the find_by_key method on the profile resource:
class ProfileResource
  def self.find_by_key(key, options = {})
    context = options[:context]
    model = context[:user]
    fail JSONAPI::Exceptions::RecordNotFound.new(key) if model.nil?
    resource_for_model(model).new(model, context)
  end
end
  • v 0.9 and 0.10: you need to call the singleton top level class method
class ProfileResource
  singleton singleton_key: -> (context) {
    key = context[:current_user].try(:preferences).try(:id)
    raise JSONAPI::Exceptions::RecordNotFound.new(nil) if key.nil?
    key
  }
end

see doc for v9 doc or v0.10

Note that your controller will also be in the singular profile_controller.rb not profiles_controller.rb

Then the singleton calls ( GET /profile, POST /profile, PUT /profile, DELETE /profile ) will work ( although the json api type will still be plural type: 'profiles', )

Note: singletons are not officially supported by the spec, so there may be clients that are not compatible with this approach.