RestClient的用法及封装

RestClient 使用笔记。

写在前面

Rest-client, 顾名思义,遵守RESTful规则的客户端,可以对服务器发出请求。

每次使用时以RestClient.get/post/put/delete起头,更高级的用法是以RestClient::Request.execute()为固定结构。

如果你的专案中多处需要用到rest-client,你一定希望可以封装起来,易于调用,让代码更优雅。

我们开始吧。

用法简介

Rest-client官方文档中, 详细地列出了各个method的参数情况,我们挑出最重要的那四个:

.get(url, headers = {}, &block)
.post(url, payload, headers = {}, &block)
.put(url, payload, headers = {}, &block)
.delete(url, headers = {}, &block)

会发现四个verb请求都带有headers,block,但是这两个参数都不是必填的。比如get, 只给一个URL就满足了。

GitHub库上有相关的实例,长这样:

用起来很简单,那么在ruby中如何封装呢?比如有个图书model,我想要对某个书进行修改,使用put时,就要传递至少三个参数,冗长的URL表明是哪本书,你的登录信息,比如sessionId, 要更新的内容。类似这样:

RestClient.post 'http://book.com/books/bookid', {:sessionId => 'XXXXXXXX', :token => "xxxx"},{"name": "XXX", "description:" "XXXXX" .......}

代码看着很不整洁,如何改进?

别急,先来看看在ruby中如何实现全局调用一个method。

call method from the global scope

比如你定义了method C

def C(name)
    puts "hello, #{name}"
end

你想要在专案的多个文件中均可以调用这个method C,怎么实现?

使用module,这么来,在文件A.rb中,放入如下内容:

module A
    module B
        def C(name)
            puts "hello, #{name}"
        end
    end
end

这时候,你引用C,需要写成A::B.C, 呃,这不是我们想要的结果,继续优化。

在Ruby中,任何一个method都绑定了一个对象。当我们调用比较常见的method,比如putsrequire时,其实我们是在调用main.puts, main.require, 也就是它们有一个默认的object,叫做main。

那我们也想给C挂上这样的object,让它也可以像puts一样被直接调用,怎么做?

让Object这个class中,包含我们的A::B即可,修改文件A.rb:

module A
    module B
        def C(name)
            puts "hello, #{name}"
        end
    end
end

class Object
    include A::B
end

这样当你在其他文件中,比如app.rb中调用C时,只要加上如下代码即可:

require 'A' #C定义的文件名
extend A::B

好,回到我们的restclient, 现在就很好做了。

简化restclient的调用

知道如何对method进行global 调用,我们可以这么玩。

新建myclient.rb文件,内容如下:

require 'rest-client'

module MyClient
  module Client
  end
end

里面没有任何method,我们加上get。

require 'rest-client'
$apiurl = http://example.com/api. #这是你API的URL,请自行修改
module MyClient
  module Client
    def get(url, headers = nil)
      response = RestClient.get(
          $apiurl + url,
          headers
      )
    end
   end
 end

class Object
  include MyClient::Client
end

这时,如果要在其他文件调用,比如app.rb文件中,使用get,就可以这么用了。

require_relative 'my_client'
extend MyClient::Client

......
headers =  {:'session' => 'XXXX'}
get("/books", headers)
.....

同样的,将post,put, delete 加入,补全代码,如下:

require 'rest-client'
$apiurl = http://example.com/api. #这是你API的URL,请自行修改
module MyClient
  module Client
    def get(url, headers = nil)
      response = RestClient.get(
          $apiurl + url,
          headers
      )
    end

    def post(url, payload, headers = nil )
      response = RestClient.post(
          $apiurl + url,
          payload,
          headers
      )
    end

    def put(url, payload, headers = nil )
      response = RestClient.put(
          $apiurl + url,
          payload,
          headers
      )
    end

    def delete(url, headers = nil )
      response = RestClient.delete(
          $apiurl + url,
          headers
      )
    end
  end
end

class Object
  include MyClient::Client
end

搞定,可以欢快地调用啦!!

参考

How can I add a method to the global scope in Ruby?