How to split things up in a grape api app?

巧了我就是萌 提交于 2019-12-03 08:10:45

问题


In every examples I see, people only implement one giant api.rb file. Ex:

  • intridea/grape
  • bloudraak/grape-sample-blog-api
  • djones/grape-goliath-example

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 :)


回答1:


The class in post.rb should be Post, not API. Then you can mount the Post API inside class API.

class API < Grape::API
  mount Blog::Post => '/'
end

To avoid confusion I would put Post in a Resources namespace, too or rename it to PostAPI.




回答2:


I found it not working for path prefix:

mount Blog::Post => '/blog'

doesn't work if you want have prefix the path.

use

namespace :blog do
   mount Blog::Post
end

Hope it helps!



来源:https://stackoverflow.com/questions/14857987/how-to-split-things-up-in-a-grape-api-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!