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 ?
Related
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.
In rails project, I made api folder and I added this code to my application.rb file:
config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
In my api folder I have created game_server.rb file:
module GameServer
module Entities
class Test < Grape::Entity
expose :id
end
end
class API < Grape::API
version 'v1', using: :path
prefix :api
format :json
get :details do
present Basis.all, with: GameServer::Entities::Test
end
end
end
All code inside GameServer module. When I hit http://localhost:3000/api/v1/details in my browser I het this error:
uninitialized constant Grape::Entity.
I even tried to put my Entities module in other file, still does not work.
WHY?
You are using old version of grape, change your grape version:
gem 'grape', '~> 0.11.0'
You can refer to this repository: https://github.com/philcallister/rails-grape-entity
Just add
gem 'grape'
gem 'grape-entity'
into your Gemfile
I've read Sinatra SASS custom directory and Sinatra custom SASS directory .
But it doesn't work for me. I write this app:
require 'sinatra'
require 'sass'
require 'slim'
configure do
set :views, :scss => 'assets/css'
end
get '/css/*.css' do
scss params[:splat].first.to_sym
end
get '/' do
slim :index
end
When I'm running it I get a error:
http://localhost:3000/css/style.css
TypeError at /css/style.css
no implicit conversion of Hash into String
It's vice versa, first :scss symbol and then :views:
configure do
set :scss, :views => 'assets/css'
end
I have this code which is in lib folder. This code works outside of rails, but when it's called from the rails controller I get the uninitialized constant AWS::S3::Base error
require 'rubygems'
require 'aws/s3'
module S3Util
def self.upload_file(local_file)
mime_type = "application/octet-stream"
bucket = "test"
AWS::S3::Base.establish_connection!(
:access_key_id => '*****',
:secret_access_key => '****'
)
base_name = File.basename(local_file)
puts "**** Uploading #{local_file} as '#{base_name}' to '#{bucket}'"
AWS::S3::S3Object.store(
base_name,
File.open(local_file),
bucket,
:content_type => mime_type
)
puts "***** Uploaded!"
end
end
just do in your controller
require 'aws/s3'
and its work for me
Rails doesn't "know" that the module is available to the application; you have to add it to the paths it looks in. You can do that in a couple of ways, but most people do the following.
Add this line to your config/application.rb:
config.autoload_paths += Dir["#{config.root}/lib/**/"]
You may, at some point, want to be more specific about which directories are searched, but this should get you going.
I've got a Rails project where a constant is being nuked at some point while serving a request.
I'm using the mime/types and restclient gems. The restclient module defines an extension to MIME which contains the method type_for_extension.
module RestClient
...
def stringify_headers headers
result[key] = target_values.map { |ext| MIME::Types.type_for_extension(ext.to_s.strip) }.join(', ')
...
end
end
end
module MIME
class Types
def type_for_extension ext
candidates = #extension_index[ext]
candidates.empty? ? ext : candidates[0].content_type
end
class << self
def type_for_extension ext
#__types__.type_for_extension ext
end
end
end
end
I can access MIME::Types.type_for_extension on my first invocation of a given controller action. On the second invocation, it's gone.
I can still use MIME::Types.type_for, but the added method is simply gone, so when I try to use the RestClient module it throws an exception on the line showin in stringify_headers:
NoMethodError, message: undefined method `type_for_extension' for MIME::Types:Class
**How is this possible? type_for_extension defined in the same file as stringify_headers; how could the latter get nuked but not the former?
EDIT: FIXED IT!
In my config:
config.gem "aws-s3", :version => ">= 0.6.2", :lib => "aws/s3"
config.gem 'mime-types', :lib => 'mime/types'
aws-s3 was loading mime-types via require_library_or_gem, which ultimate invoked ActiveSupport::Dependencies.autoload_module! which maintains a table called autoloaded_constants which are nuked when ActionController.close calls Dispatcher.cleanup_application.
Fix was to load mime-types first, so it's not autoloaded.
*whew*
Answering my own question by request.
In my config:
config.gem "aws-s3", :version => ">= 0.6.2", :lib => "aws/s3"
config.gem 'mime-types', :lib => 'mime/types'
aws-s3 library was loading mime-types via require_library_or_gem, which ultimately invoked ActiveSupport::Dependencies.autoload_module! which maintains a table called autoloaded_constants which are nuked when ActionController.close calls Dispatcher.cleanup_application.
Fix was to load mime-types first, so it's not autoloaded.