How to build named helper using Grape on rails - ruby-on-rails

I'm using grape gem; ref https://github.com/intridea/grape.
Could you show me how to build named path like "twitter_api_v1_statuses_path" ?
My code is as follows
module Twitter
class API < Grape::API
version 'v1', using: :header, vendor: 'twitter'
format :json
prefix :api
resource :statuses do
desc "Return a public timeline."
get :public_timeline do
Status.limit(20)
end
end
end

I'm assuming that you want an URL like this http://yourdomain.com/api/v1/statuses/public_timeline. In this scenario, you have only one problem in your API class and it's related to the versioning strategy you've chosen. The :header strategy search for the API version in a specific header and that's not what you're looking for. Change it to :path.
module Twitter
class API < Grape::API
version 'v1', using: :path, vendor: 'twitter'
format :json
prefix :api
resource :statuses do
desc "Return a public timeline."
get :public_timeline do
Status.limit(20)
end
end
end
end

Related

Grape add new endpoint

I'm using Rails 6 with Grape as API. I'm pretty new in Grape and I'm trying to learn how to add new endpoint using Grape. The idea is to get Index endpoint which is nested in v1/users/index
Here is my structure:
app/
controllers/
api/
root.rb - API::Root
v1/
base.rb - API::V1::Base
users/
base.rb - API::V1::Users::Base
index.rb - API::V1::Users::Index
api/root.rb
module API
class Root < Grape::API
default_format :json
prefix :api
# exception handling
include Rescuers
# helpers
helpers ::API::Helpers::ParamsHelper
# core API modules
mount V1::Base
end
end
api/v1/base.rb:
module API
module V1
class Base < Root
version 'v1', using: :path
content_type :json, 'application/vnd.api+json'
# mount resource modules
mount V1::Users::Base
end
end
end
api/v1/users/base.rb:
module API
module V1
module Users
class Base < Grape::API
version 'v1', using: :path
content_type :json, 'application/vnd.api+json'
# mount resource modules
mount Users::Index
end
end
end
end
api/v1/users/index.rb:
module API
module V1
module Users
class Index < Grape::API
desc 'Test'
get do
head 200
end
end
end
end
end
Here are my routes:
Rails.application.routes.draw do
# API
scope :api do
mount API::Root, at: '/'
end
end
I want to have this index.rb in my routes as GET v1/users/index but when I type rake routes I don't see it. This should not do anything, I want to understand what is the core requirements when it comes to creation endpoint with Grape.

Rails: how to make url with multi slash in Grape

I'm using grape for restful service. As I know, :resource will define a path in url. For example:
module Sample
module V1
module Order
class GetCheckInListApi < ApplicationApi
resource :check_in_list do
get root: :data do
# business code here
end
end
end
end
end
end
The url for example, will be: localhost:8000/api/v1/check_in_list. I want the url should be: localhost:8000/api/v1/check_in/list. How can I do in Grape ?
Thanks
Does the resource has to be a :check_in_list? You could change it to :chect_in and add a /list route:
class GetCheckInListApi < ApplicationApi
resource :check_in do
get '/list' do
# business code here
end
end
end

Rails Grape show 404 page

I am a beginner in Grape, I want to show my api list by using swagger-ui.
I put swagger html in public/swagger, and I access localhost:3000/swagger
However, it keep showing 404 not found. I thought it's causing by Grape configuration.
Here is api.rb
#app/api/twitter/api/api.rb
require 'grape'
module Twitter
class API < Grape::API
version 'v1', using: :header, vendor: 'twitter'
format :json
prefix :api
add_swagger_documentation
resource :statuses do
desc 'Return a public timeline.'
get :public_timeline do
Status.limit(20)
end
end
end
end
You don't have to do it manually by putting swagger html somewhere.
You could use gem grape-swagger provided by Grape team, add two lines in you config.ru.
require 'grape-swagger'
module API
class Root < Grape::API
format :json
...
add_swagger_documentation
end
end
then you could access swagger doc at http://localhost:3000/swagger_doc

Inheritance is not working in grape

I am using grape redtful-api. I am Unable to inherit common_params in Grape. I defined common
_params in class API1 and called it in API2 throws the error. How can I change the code to make this work?
module Example
class API1 < Grape::API
version 'v1'
format :json
prefix :api
resource :exc1 do
common_params = proc do
requires :param1
requires :param2
end
params(&common_params)
get :params_by_pair do
p1 = params[:param1]
p2 = params[:param2]
response = "https://www.example1.com/#{p1}_#{p2}"
end
end
end
end
module Example
class API2 < API1
version 'v1', using: :header, vendor: 'twitter'
format :json
prefix :api
resource :exc2 do
params(&common_params)
get :params_by_pair do
p1 = params[:param1]
p2 = params[:param2]
response = "https://www.example2.com/#{p1}_#{p2}"
end
end
end
end
The issue doesn't have much to do with Grape but rather the way variables' scope works in Ruby. common_params is just a local, it won't survive the end of the scope. You could make it work by using a class instance variable or similar but let's not go there. The way you're supposed to share helpers across different grapes is through a dedicated module.
module Example
module SharedHelpers
extend Grape::API::Helpers
params :common_params do
requires :param1
requires :param2
end
end
end
And now in the different grapes you need to "include" the module and use the helper.
module Example
class API1 < Grape::API
helpers SharedHelpers # !!!
version 'v1'
format :json
prefix :api
resource :exc1 do
params do
use :common_params # !!!
end
get :params_by_pair do
...
end
end
end
end
To use the helpers in the API2 grape, use the same technique.

Rails Grape, DRY Helpers call for shared params

Objective: Use grape Shared Params from a helper module, without having to add the syntax helpers Helper::Module on every mounted API.
Example code that works:
# /app/api/v1/helpers.rb
module V1
module Helpers
extend Grape::API::Helpers
params :requires_authentication_params do
requires :user_email, type: String
requires :authentication_token, type: String
end
end
end
# /app/api/api.rb
class API < Grape::API
format :json
version 'v1', using: :path
mount V1::A
mount V1::B
end
# /app/api/v1/a.rb
module V1
class A < Grape::API
helpers V1::Helpers
desc 'SampleA'
params do
use :requires_authentication_params
end
get 'sample_a/url' do
#...
end
end
end
# /app/api/v1/B.rb
module V1
class B < Grape::API
helpers V1::Helpers
desc 'SampleB'
params do
use :requires_authentication_params
end
get 'sample_b/url' do
#...
end
end
end
The problem arise when I try to move the helpers V1::Helpers call from A and B to the API class that mounts them, throwing the exception:
block (2 levels) in use': Params :requires_authentication_params not found! (RuntimeError)
As an interesting note, the module does get included, because if I add any instance method to the class V1::Helpers I can use them inside A and B.
So the question, What would be the best solution to DRY this and follow best practices?
What if you include V1::Helpers on API and then make A and B inherit from API? E.g:
# /app/api/api.rb
class API < Grape::API
include V1::Helpers
format :json
version 'v1', using: :path
mount V1::A
mount V1::B
end
class A < API
# ...
end
class B < API
# ...
end

Resources