In every examples I see, people only implement one giant api.rb file. Ex:
While this approach works fine as is, it can quickly become crowded and difficult to maintain so I would like to split things up on my app.
For instance, I would like to split my entities from my resources, and then split up my resources between different files. For examples:
app
- api
api.rb
- entities
- weblog.rb
- post.rb
- comment.rb
- resources
- weblog.rb
- post.rb
- comment.rb
Now, api.rb would be something like:
require 'grape'
module Blog
class API < Grape::API
prefix "api"
end
end
app/api/entities/post.rb would be something like:
module Blog
module Entities
class Post < Grape::Entity
root 'posts', 'posts'
expose :id
expose :content
end
end
end
app/api/resources/post.rb would be something like:
module Blog
class API < Grape::API
resource :posts do
get do
present Post.all, with: Blog::Entities::Post
end
desc "returns the payment method corresponding to a certain id"
params do
requires :id, :type => Integer, :desc => "Post id."
end
get ':id' do
present Post.find(params[:id]), with: Blog::Entities::Post
end
end
end
end
When we do this, we encounter the following message:
Expected /blog-app/api/resources/post.rb to define Post
SOLUTION (thanks to dB. and my co-workers)
You have to change the structure to something like:
app
- api
api.rb
- resources
- post_api.rb
Then, in the post_api.rb
module Blog
class Resources::PostAPI < Grape::API
resource :posts do
get do
present Post.all
end
end
end
end
Finally, the api.rb becomes:
require 'grape'
module Blog
class API < Grape::API
prefix 'api'
version 'v1', :using => :path
format :json
mount Blog::Resources::PostAPI => '/'
end
end
Now /api/v1/posts
should work :)
I found it not working for path prefix:
doesn't work if you want have prefix the path.
use
Hope it helps!
The class in post.rb should be Post, not API. Then you can mount the Post API inside class API.
To avoid confusion I would put Post in a Resources namespace, too or rename it to PostAPI.