I am trying to use grape-swagger gem for creating the auto-generated documentation for my Grape API.
Using 'grape' gem I have created few APIs.
Example:
http://localhost:9292/api/v1/charges
This API is working fine.
Following documentation of 'grape-swagger', I am not able to generate the API documentation properly.
My steps:
I added below in the gemfile
gem 'grape-swagger'
I also used rack-cors to enable CORS by adding below in config.ru
require 'rack/cors'
use Rack::Cors do
allow do
origins ''
resource '', headers: :any, methods: [ :get, :post, :put, :delete, :options ]
end
end
Also added below in gemfile.
gem 'rack-cors', :require => 'rack/cors'
Also I added below at the end in my API class
add_swagger_documentation
But when I run http://localhost:9292/api/v1/swagger_doc, I am not getting the proper paths.
I need the API path like http://localhost:9292/api/v1/charges, but it is returning as http://localhost:9292/api/v1/swagger_doc/charges
Do I need to set any other configuration?
In end of api class add below params for hide documentation path:
add_swagger_documentation hide_documentation_path: true, api_version: 'v1'
If you want to use this gem grape-swagger-rails then use this configuration as per documentation:
Then create file named config/intializers/swagger.rb and add this line for customization:
GrapeSwaggerRails.options.url = "/api/v1/swagger_doc"
GrapeSwaggerRails.options.app_url = "#{ENV['APPLICATION_URL']}"
where you can set APPLICATION_URL in environment variables like : localhost:3000
And your config/routes.rb file set route as
mount GrapeSwaggerRails::Engine => '/swagger'
Then you can access all docs from here: localhost:3000/swagger
This way you can customize your swagger documentation with grape api.
Related
I am setting up my Rails API server following this tutorial: building-awesome-rails-apis-part-1
Everything works well, except the part that mentions that it is not necessary to indicate the namespace in the route. Eg.
Now our URls look like: http://api.example.com/v1/people or just
http://api.example.com/people if you don’t use the version, it
doesn’t interfere with your regular people routes, and it looks great.
When I call http://api.mydomain.com/v1/therapists/ it works, but when I try to omit the v1 namespace in the URL it's not working, do I need to do any extra configuration?
I'm using Rails 6.0.3.4
This is my specific routes.rb file:
Rails.application.routes.draw do
namespace :api, :path => "", :constraints => {:subdomain => "api"} do
namespace :v1 do
resources :therapists do
resources :appointments
end
end
end
end
Solution
As zhisme suggested, I used rack-rewrite gem to do what I wanted.
First, I added the gem to my Gemfile:
gem 'rack-rewrite', '~> 1.5', '>= 1.5.1'
After that I added the configuration in config/application.rb file
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
rewrite '/therapists', '/v1/therapists'
end
And it worked.
In order to achieve this, you will need to insert inside Rack code. There is a gem rack-rewrite that can do redirects before Rails code execute, thus before rails routes resolving. Check their README for installation.
so modifying README example to your question, you can do something like
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
rewrite '/api/therapists/appointments', '/api/v1/therapists/appointments'
end
or you can make redirects to give your api consumers to know that correct url is a bit different
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
moved_permanently '/api/therapists/appointments', '/api/v1/therapists/appointments'
end
There is quite good article describing different solutions, take a look for more details.
If you omit the v1 namespace in the URL, you must also remove it from your routes.rb file.
The quote from the tutorial stated "or just http://api.example.com/people if you don’t use the version", meaning if you don't include the v1 namespace in the routes.rb file.
I have been learning Ruby on Rails, but I still have issues when it comes to Ruby gems with examples that are irb based and not Rails or Sinatra framework based. I am trying to implement the Block.io Bitcoin API functionality. But the code I find is Ruby only, so I am not sure where to create a config file for the API Key and also whether I need to create a controller to make this work in the views for Rails.
The gem and examples are on: https://github.com/BlockIo/gem-block-io
I installed this gem via bundle install on Rails
gem install block_io -v=1.0.6
The Ruby example show the following:
>> require 'block_io'
>> BlockIo.set_options :api_key=> 'API KEY', :pin => 'SECRET PIN', :version => 2
In Rails which config file would I enter the above api_key and pin?
In the example they show the code to get your address as follows:
BlockIo.get_my_address
Do I need to create a function in a controller such as:
def address
#my_address = BlockIo.get_my_addresses
end
and in the view use:
<%= #my_address %>
I need some guidance with regards to the above, any comment or assistance will be greatly appreciated.
require 'block_io' can go into Gemfile like gem 'block_io'. Rails/bundler will require it automaticaly for you as long as the gem name is also the file name you want to require from this gem.
BlockIo.set_options :api_key=> 'API KEY', :pin => 'SECRET PIN', :version => 2 can be put into an initilizer like config/initializers/block_io.rb. This way set_options is called only once when Rails starts a server or console or runner.
Put it like this into the file config/initializers/block_io.rb
BlockIo.set_options :api_key=> ENV['BLOCK_IO_API_KEY'], :pin => ENV['BLOCK_IO_PIN'], :version => 2
With the environment variables in use you don't commit any secret into your repo.
Now you should be able to call BlockIo.get_my_address within any action.
Below is the configuration I used to build API's using Grape.
But I am not able to build documentation using Swagger
Gems:
gem 'grape'
grape-0.13.0
gem 'grape-swagger-rails'
grape-swagger-rails-0.1.0
gem 'rack-cors', :require => 'rack/cors'
rack-cors-0.4.0
config/application.rb
require 'rack/cors'
config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'api', '**', '*.rb')]
config/initializers/swagger.rb
GrapeSwaggerRails.options.url = '/swagger_doc.json'
GrapeSwaggerRails.options.app_url = "http://api.lvh.me:3000"
config/routes.rb
constraints(subdomain: 'api') do
mount API::Base => '/'
end
mount GrapeSwaggerRails::Engine, at: "/apidocs"
app/api/api/base.rb
require 'grape-swagger'
module API
class Base < Grape::API
default_format :json
mount API::V1::Base
add_swagger_documentation(
api_version: "v1",
hide_documentation_path: true,
mount_path: "/",
hide_format: true
)
end
end
Issue:
When I hit http://lvh.me:3000/apidocs. I'm getting below error below green Nav bar.
Can't read swagger JSON from http://api.lvh.me:3000/swagger_doc.json
When I hit http://api.lvh.me:3000/swagger_doc.json. Getting below response.
{"error":"Not Found"}
I am not able to figure out what am doing wrong. Need help in rendering Swagger documentation with grape framework.
In config/initializers/swagger.rb you set the URL to your schema to /swagger_doc.json and to mount_path in the method add_swagger_documentation you pass '/'. Shoudn't it be /swagger_doc ?
I'm writing a gem and I'm going to use it with Rails 4. Is it possible for me to add a route from my Gem rather than from config/routes.rb in my rails project? I want this to be inside a gem so I can include it in more than one Rails project without having to configure every Rails project, rather do it once in the gem. Is that possible and how?
i.e :
If my routes were :
get 'test' => 'users#test'
how would that translate into my gem. If my gem were used as an engine just like RB suggested in his answer :
module Blorgh
class Engine < ::Rails::Engine
get 'test' => 'users#test'
end
end
This doesn't work, what am I doing wrong?
Read the Engine Guide of Ruby on Rails. Basically you'll want to create the file in config/routes.rb (on your gem folder) and add the following:
YourGemName::Engine.routes.draw do
get 'test' => 'users#test'
end
Yes it is possible if you make your gem an engine.
Read the Getting Started with Engines guide.
I am trying login with gmail and OmniAuth in rails 3. I am following http://hoisie.com/2011/09/12/using-google-oauth-with-omniauth/ this post. I added gem 'omniauth'
in my gem file. Create omniauth.rb inside initializers. Replace the oauth_secret by API key generated in google api site.
Create sessions controller and adding
match "/auth/:provider/callback" => "sessions#create"
match "/signout" => "sessions#destroy", :as => :signout
this in my route.rb
When i am running the app getting the following error.
/usr/lib/ruby/gems/1.8/gems/omniauth-1.0.1/lib/omniauth/builder.rb:25:in `provider': Could not find matching strategy for :google. You may need to install an additional gem (such as omniauth-google). (LoadError)
There is an omniauth strategy for Google, it is omniauth-google-oauth2. Just just add it to your Gemfile as you are adviced in the error message.
You may also want to look at my example app that includes authenticating via omniauth.