I would like someone to explain why this is happening in Rails (4.1.8) with Grape (0.10.1)
so this is my API:
app/api/root.rb
:
module API
class Root < Grape::API
prefix 'api'
mount API::V1::Root
end
end
app/api/v1/root.rb
:
module API::V1
class Root < Grape::API
version 'v1'
mount API::V1::Users
end
end
app/api/v1/users.rb
:
module API::V1
class Users < Grape::API
format 'json'
resource :users do
desc "Return list of users"
get '/' do
User.all
end
end
end
end
config/routes.rb
:
Rails.application.routes.draw do
mount API::Root => '/'
end
and in my application.rb
I added:
config.paths.add "app/api", glob: "**/*.rb"
config.autoload_paths += Dir["#{Rails.root}/app/api/*"]
and in that case I get the error: NameError: uninitialized constant API
but if my code looks like:
app/api/root.rb
same as above
then app/api/v1/root.rb
:
class Root < Grape::API
version 'v1'
mount Users
end
app/api/v1/users.rb
:
class Users < Grape::API
format 'json'
resource :users do
desc "Return list of users"
get '/' do
User.all
end
end
end
config/routes.rb
:
Rails.application.routes.draw do
mount Root => '/'
end
and config/application.rb
same as above
Then everything works fine.
My question is why don't I need to specify modules inside v1/root.rb
and also inside v1/users
and also why I don't need to use API::Root => '/'
in config/routes.rb
?
It's because
app/api
is the top-level folder for your API classes, notapp
.From Grape's documentation:
Therefore the correct location for an
API::Root
class would actually beapp/api/api/root.rb
, not/app/api/root.rb
—though that is the correct location for a class in the top-level namespace, which is why the second example you give (with classes removed from theAPI
module) works.I recommend you keep your API classes together in their own module, though, and move them to a matching subfolder beneath
app/api
.I tried to put my files into
app/api/api
, but it wasn't working for me.I found a solution by simply putting the
api
folder into thecontroller
folder. I'm not 100% sure what the problem was, but my guess is that it has something to do with the auto-loaded paths.