Module: APIResourceFieldsettable

Extended by:
ActiveSupport::Concern
Included in:
API::APIDataManagement, API::Open, API::V1
Defined in:
app/api/concerns/api_resource_fieldsettable.rb

Overview

Helper To Make Resource APIs Fieldsettable

By making an API fieldsettable, you let API callers to choose the fields they wanted to be returned with query parameters. This is really useful for making API calls more efficient and fast.

This design made references to the rules of Sparse Fieldsets in JSON API: jsonapi.org/format/#fetching-sparse-fieldsets

A client can request that an API endpoint return only specific fields in the response by including a fields parameter, which is a comma-separated (“,”) list that refers to the name(s) of the fields to be returned.

GET /users?fields=id,name,avatar_url

This functionality may also support requests specifying multiple fieldsets for several objects at a time (e.g. another object included in an field of another object) with fields[object_type] parameters.

GET /posts?fields[posts]=id,title,author&fields[user]=id,name,avatar_url

Note: author of a post is a user.

The fields and fields[object_type] parameters can not be mixed. If the latter format is used, then it must be used for the main object as well.

Usage

Include this Concern in your Grape API class:

class SampleAPI < Grape::API
  include APIResourceFieldsettable
end

then set the options for the fieldset in the grape method:

resources :posts do
  get do
    fieldset_for :post, root: true, default_fields: [:id, :title, :author]
    fieldset_for :user, permitted_fields: [:id, :name, :posts, :avatar_url],
                        show_all_permitted_fields_by_default: true
    # ...
  end
end

Further usage of fieldset_for method can be found in the docs of the HelperMethods class.

This helper parses the fields and fields[object_type] parameters to determine what the API caller wants, and save the results into instance variables for further usage.

After this you can use the fieldset helper method to get the fieldset data that the request specifies.

With GET /posts?fields=title,author:

fieldset #=> { post: [:title, :author], user: [:id, :name, :posts, :avatar_url] }

With GET /posts?fields[post]=title,author&fields[user]=name:

fieldset #=> { post: [:title, :author], user: [:name] }
fieldset(:post) #=> [:title, :author]
fieldset(:post, :title) #=> true
fieldset(:user, :avatar_url) #=> false

You can make use of the information while dealing with requests, for example:

Post.select(fieldset(:post))...

If you're using RABL as the API view, it can be also setup like this:

object @user

# this ensures the +fieldset+ instance variable is least setted with
# the default fields, and double check +permitted_fields+ at view layer -
# in case of things going wrong in the controller
set_fieldset :user, default_fields: [:id, :name, :avatar_url],
                    permitted_fields: [:id, :name, :avatar_url, :posts]

# determine the fields to show on the fly
attributes(*fieldset[:user])

Defined Under Namespace

Modules: HelperMethods

Class Method Summary collapse

Class Method Details

.fields_param_desc(example: nil) ⇒ Object

Return the 'fields' param description


165
166
167
168
169
170
171
# File 'app/api/concerns/api_resource_fieldsettable.rb', line 165

def self.fields_param_desc(example: nil)
  if example.present?
    "Choose the fields to be returned. Example value: '#{example}'"
  else
    "Choose the fields to be returned."
  end
end