Helpers

Grape allows you to define helper methods that can be used within your endpoints, making your code cleaner and more organized. You can define helpers directly in a block or by including modules.

Defining Helpers

Use the helpers block to define methods that will be available within the current namespace and any nested namespaces.

class MyAPI < Grape::API
  helpers do
    def current_user
      @current_user ||= User.find_by_token(params[:token])
    end

    def authenticate!
      error!('401 Unauthorized', 401) unless current_user
    end
  end

  get '/profile' do
    authenticate!
    # The current_user helper is available here
    present current_user, with: UserEntity
  end
end

Including Helper Modules

For better organization, you can define helpers in modules and include them in your API.

# app/api/helpers/auth_helpers.rb
module AuthHelpers
  def current_user
    # ...
  end

  def authenticate!
    # ...
  end
end

# app/api/my_api.rb
class MyAPI < Grape::API
  helpers AuthHelpers

  get '/profile' do
    authenticate!
    # ...
  end
end

Shared Parameters

One of the most powerful uses of helpers is to define reusable parameter blocks. This is especially useful for common patterns like pagination or date filtering.

Defining Shared Params

To create shared parameters, define a module, extend it with Grape::API::Helpers, and use the params method within it.

# app/api/helpers/shared_params.rb
module SharedParams
  extend Grape::API::Helpers

  params :pagination do
    optional :page, type: Integer, desc: 'Page number.'
    optional :per_page, type: Integer, desc: 'Number of items per page.'
  end

  params :date_range do
    optional :start_date, type: Date
    optional :end_date, type: Date
  end
end

Using Shared Params

First, include the module with helpers, then use the use (or includes) keyword within a params block to apply the shared parameters.

class MyAPI < Grape::API
  helpers SharedParams

  desc 'Get a collection of items.'
  params do
    use :pagination
    use :date_range
  end
  get do
    items = Item.all
    items = items.where('created_at >= ?', params[:start_date]) if params[:start_date]
    items = items.where('created_at <= ?', params[:end_date]) if params[:end_date]
    items.page(params[:page]).per(params[:per_page])
  end
end

You can also pass options to your shared params blocks to make them more dynamic.

# In your helper module
params :order do |options|
  optional :order_by, type: Symbol, values: options[:order_by], default: options[:default_order_by]
  optional :order, type: Symbol, values: %i[asc desc], default: options[:default_order]
end

# In your API
params do
  use :order, order_by: %i[id created_at], default_order_by: :created_at, default_order: :asc
end
get do
  Collection.order("#{params[:order_by]} #{params[:order]}")
end