Recently while building a Single Page Application (SPA) there came up a need to get the current_user’s information (in our case, it’s a current_account). Without going into details on how to figure out the current account, this post will show you how to return a valid JSONAPI object using jsonapi-resources.

Let’s get a few assumptions out of the way. You have a current_account setup in your ApplicationController (using devise or another approach), and you have jsonapi-resource setup and working in your application.

To make this, we need two items:

  1. Resource – Represents our rails model in JSONAPI-resource format
  2. Serializer – Used to serialize the resource

Let’s create a new controller:
rails generate controller api/v1/profile

Now we add the following:

class Api::V1::ProfileController < ApplicationController
  def show
    render json: resource_serializer.serialize_to_hash(current_resource)
  end

  #######
  private
  #######

  def resource_serializer
    @resource_serializer ||= JSONAPI::ResourceSerializer.new(Api::V1::AccountResource)
  end

  def current_resource
    # Must return nil if current_account doesn't exist
    # otherwise you will return an AccountResource that is blank (vs nil)
    return nil unless current_account

    # Note: `new` takes two args, first is the model, second is the context
    @current_resource ||= Api::V1::AccountResource.new(current_account, {})
  end
end

Next, we need to make sure we add the new controller to the routes:

namespace :api do
  namespace :v1 do
    resource :profile, controller: :profile, only: [:show]
    jsonapi_resources :accounts
    # and so on...
  end
end

Now you can try to send your request (http://localhost:3000/api/v1/profile.json) and the response is:

{
  "data": {
    "id": "1",
    "type": "accounts",
    "links": {
      "self": "/api/v1/accounts/1"
    },
    "attributes": {
      "firstName": "Admin",
      "lastName": "User",
      "email": "[email protected]",
      "fullName": "Admin User"
    }
  }
}

Note that the type is "accounts" because the resource that we fetched is an account. If you were to fetch more details or relationships, you’d be using the account API and not the profile API.

That’s all for now, but please leave any comments or warnings below!