grape入门

1.Grape是运行在rack或与rails/sinatra配合使用的一种restful风格的ruby微框架,通过提供简单的DSL(领域特定语言)简化APIs开发.它内置支持mutiple formats(),subdomain/prefix restriction, versioning等通用约束(ruby约束高于配置).详见http://intridea.github.io/grape/.

2.安装Grape

gem install grape

或者编辑Gemfile.

gem "grape"

然后

bundle install

 

3.基础用法

Grape APIs和Rack应用继承自Grape::API.

下面展示一段用Grape写的简单的twitter API:

module Twitter

  class API < Grape::API

    version 'v1', using: :header, vendor: 'twitter'

    format :json 

    prefix :api



    helpers do

      def current_user

        @current_user ||= User.authorize!(env)

      end



      def authenticate!

        error!('401 Unauthorized', 401) unless current_user

      end

    end



    resource :statuses do

      desc "Return a public timeline."

      get :public_timeline do

        Status.limit(20)

      end



      desc "Return a personal timeline."

      get :home_timeline do

        authenticate!

        current_user.statuses.limit(20)

      end



      desc "Return a status."

      params do

        requires :id, type: Integer, desc: "Status id."

      end

      route_param :id do

        get do

          Status.find(params[:id])

        end

      end



      desc "Create a status."

      params do

        requires :status, type: String, desc: "Your status."

      end

      post do

        authenticate!

        Status.create!({

          user: current_user,

          text: params[:status]

        })

      end



      desc "Update a status."

      params do

        requires :id, type: String, desc: "Status ID."

        requires :status, type: String, desc: "Your status."

      end

      put ':id' do

        authenticate!

        current_user.statuses.find(params[:id]).update({

          user: current_user,

          text: params[:status]

        })

      end



      desc "Delete a status."

      params do

        requires :id, type: String, desc: "Status ID."

      end

      delete ':id' do

        authenticate!

        current_user.statuses.find(params[:id]).destroy

      end

    end

  end

end

关于上面代码的简单解释:

将API文件放在/app/api文件下,并且修改/config/application.rb文件:

config.paths.add "app/api", glob: "**/*.rb"

config.autoload_paths += Dir["#{Rails.root}/app/api/*"]

并且修改路由文件/config/routes.rb:

mount   Twitter::API  => '/'

 

3.调用API

使用mount方法:

class Twitter::API < Grape::API

  mount Twitter::APIv1

  mount Twitter::APIv2

end
class Twitter::API < Grape::API

  mount Twitter::APIv1 => '/v1'

end

4.为API添加描述

desc "Returns your public timeline." do

  detail 'more details'

  params  API::Entities::Status.documentation

  success API::Entities::Entity

  failure [[401, 'Unauthorized', "Entities::Error"]]

  named 'My named route'

  headers [XAuthToken: {

             description: 'Valdates your identity',

             required: true

           },

           XOptionalHeader: {

             description: 'Not really needed',

            required: false

           }

          ]

end

get :public_timeline do

  Status.limit(20)

end

details:更加详细的描述

params:直接从实体定义参数

success:实体对象的默认使用路由

failure:请求失败返回的http代码

(====续=====)

参数认证和约束

(1).在block中定义设置参数的约束项:

params do

  requires :id, type: Integer  

  optional :text, type: String, regexp: /^[a-z]+$/  #text全是小写字母

  group :media do #参数嵌套;与[:id]协同

    requires :url

  end

end

put ':id' do

  # params[:id] is an Integer

end

(2).命名空间认证和约束

允许定义参数以及在命名空间内部使用各种方法,命名空间就是一个sandbox,叫做module;采用这种模块化机制可以有效限定作用域;

namespace :statuses do

  params do

    requires :user_id, type: Integer, desc: "A user ID."

  end

  namespace ":user_id" do

    desc "Retrieve a user's status."

    params do

      requires :status_id, type: Integer, desc: "A status ID."

    end

    get ":status_id" do

      User.find(params[:user_id]).statuses.find(params[:status_id]) #通过 :user_id获取:status_id;

    end

  end

end

(3)用户认证

class AlphaNumeric < Grape::Validations::Validator

  def validate_param!(attr_name, params)

    unless params[attr_name] =~ /^[[:alnum:]]+$/  #[:alnum]  posix字符类字母数字类

      throw :error, status: 400, message: "#{attr_name}: must consist of alpha-numeric characters"

    end

  end

end
params do

  requires :text, alpha_numeric: true  #也可这样约束类型

end
class Length < Grape::Validations::SingleOptionValidator

  def validate_param!(attr_name, params)

    unless params[attr_name].length <= @option

      throw :error, status: 400, message: "#{attr_name}: must be at the most #{@option} characters long"

    end

  end

end
params do

  requires :text, length: 140

end

请求头

get do

  error!('Unauthorized', 401) unless headers['Secret-Password'] == 'swordfish'

end



get do

  error!('Unauthorized', 401) unless env['HTTP_SECRET_PASSWORD'] == 'swordfish'

end
header "X-Robots-Tag", "noindex"

路由

 

get ':id', requirements: { id: /[0-9]*/ } do  #Regexp 条件过滤

  Status.find(params[:id])

end



namespace :outer, requirements: { id: /[0-9]*/ } do

  get :id do

  end



  get ":id/edit" do

  end

end
module StatusHelpers

  def user_info(user)

    "#{user} has statused #{user.statuses} status(s)"

  end

end



class API < Grape::API

  # define helpers with a block

  helpers do

    def current_user

      User.find(params[:user_id])

    end

  end



  # or mix in a module

  helpers StatusHelpers



  get 'info' do

    # helpers available in your endpoint and filters

    user_info(current_user)

  end

end

 

你可能感兴趣的:(rap)