首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

了解 Ruby 中的具象状态传输 (REST)-2

了解 Ruby 中的具象状态传输 (REST)-2

自描述数据简介在各个异构系统之间的通信引入了一些有趣的问题,其中一个就是用于传输的数据序列化。机器以各种方式(从不同的浮点表示法到标准的字节次序冲突)来表示数据。早期实现包括抽象语法表示法 (Abstract Syntax Notation, ASN.1) 格式和外部数据表示 (External Data Representation, XDR) 协议(在 Network File System 内使用)。其他方法包括 XML,此 XML 在 ASCII 格式化的文档中对数据进行编码。
在过去的六年中,JSON 格式已经备受瞩目。正如其名称所示,JSON 来源于 JavaScript 语言,且用于表示自描述数据结构(比如关联数组)。撇开其名称,JSON 还是一种常见的数据交换格式,支持多种语言。它同样对读取无关紧要。
现在,看一个 JSON 示例,尤其是通过 CrunchBase REST 接口的一个示例。该例使用了交互式的 Ruby shell (irb),允许您实时试用 Ruby。
如  所示,从执行交互式 Ruby shell 开始。通过加载一些模块(尤其是 JSON 和 HTTP 组件),以及定义自己的 URL 来准备您的环境。此处需要注意的是,URI 是一个完整的 CrunchBase 请求(在 Company 名称空间中,使用 ibm 的永久链接)。您将此提供给 Net::HTTP 的 get_response 方法,Net::HTTP 是在指定 URL(通过 URI.parse 方法解析为其单个组件)上执行 GET 请求的一种快捷方式。如果发出了 resp.body,您就可以看到返回的 JSON 数据。该数据包括一组名称/值对(比如 “name” 和 “IBM”)。使用 JSON.parse 方法将响应结果解析成一个 Ruby 对象结构。最后,您可以通过指定值的名称来提取特定的值。
清单 2. 使用 Ruby 与 CrunchBase 进行交互
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'json'
=> true
irb(main):003:0> require 'net/http'
=> true
irb(main):004:0> uri = "http://api.crunchbase.com/v/1/company/ibm.js"
=> "http://api.crunchbase.com/v/1/company/ibm.js"
irb(main):005:0> resp = Net::HTTP.get_response(URI.parse(uri))
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):006:0> puts resp.body
{"name": "IBM",
"permalink": "ibm",
"crunchbase_url": "http://www.crunchbase.com/company/ibm",
"homepage_url": "http://www.ibm.com",
"blog_url": "",
"blog_feed_url": "",
"twitter_username": "",
"category_code": "software",
"number_of_employees": 388000,
...
=> nil
irb(main):007:0> parsedresp = JSON.parse(resp.body)
=> {"updated_at"=>"Wed Feb 01 03:10:14 UTC 2012", "alias_list"=>nil,
...
irb(main):008:0>
irb(main):009:0* puts parsedresp['founded_year']
1896
=> nil
irb(main):010:0>




从  中,您可以看到,将从一个 JSON 响应(7 个行)中快速提取数据进行原型化是很简单的一件事。现在,继续采取这一步骤构建一个简单、可重用的 API 以便与 CrunchBase 进行交互。
构建一个简单的 REST 客户端构建 REST 客户端之前,必需安装一些内容。如果还没有安装 Ruby,那么就先安装。因为我使用的是 Ubuntu,所以我使用 Advanced Packaging Tool(其次使用 Ruby gem 包管理器)来满足大多数安装需求。
使用下列代码捕获 Ruby 包:
1
$ sudo apt-get install ruby




或者,捕获 Interactive Ruby Shell (irb),这是试用 Ruby 语言的一种有用方式:
1
$ sudo apt-get install irb




最后,您需要对 Ruby 使用 JSON gem。下列代码展示了如何同时获取 gem 前端和 JSON gem。
1
2
3
$ sudo apt-get install rubygems1.8
$ sudo apt-get install ruby-dev
$ sudo gem install json




准备好环境之后,开始使用 Ruby 构建简单的 REST 客户端 API。在  中,您可以看到如何使用 Ruby 与一个 HTTP 服务器进行通信,以及如何从 JSON 对象中解析一个简单的名称。以这种知识为基础,使用一组 Ruby 类来实现一个简单的 API。
首先,考虑使用与 CrunchBase REST 服务器交互的两个样例类。第一个类专注于 Company 名称空间;第二个类专注于 Person 名称空间。请注意,这两个类都将扩展方法的最小集,但对其他数据元素来说也很轻易进行扩展。
提供了 API,以便与 Company 名称空间进行交互。该类扩展了构造函数方法 (initialize),以及用于从基于 JSON 企业记录中提取数据的四种方法。该类的操作原理是:用户创建一个对象实例,从而提供了一个企业(永久链接)名称。作为构造函数的一部分,CrunchBase 用于请求企业记录。您可以动态构造 URL,这就将所传递的企业名称添加为 new 方法的一部分。get_response 方法用于检索响应,并将解析结果(一个散列对象)加载到一个实例变量 (@record) 中。
解析记录可用之后,每种方法在调用时只提取所需的数据并将其返回给用户。founded_year、num_employees 和 company_type 方法直观明了,前提是具有来自  的讨论。people 方法需要稍作解释。
来自 CrunchBase 的 JSON 响应是由一个包含一些密钥的散列来表示。请注意,在前三个方法中,您指定了返回值的密钥。people 方法对由密钥 relationships 识别的散列进行迭代。每个记录包含一个 is_past 密钥(用于确定 Person 是否已经不在某个 Company 中工作)、一个 title 密钥,以及一个 Person 密钥,Person 密钥包含 first_name、last_name 和 permalink。迭代程序仅仅是遍历每一个密钥,当密钥 is_past 错误时,提取 person 和 title,并从该信息中创建一个新的散列。当找不到更多密钥时,则会返回该散列。请注意,您只需发出 JSON.parse 响应即可查看 IRB 中的全部散列。
清单 3. Company 名称空间 (company.rb) 的 Ruby CrunchBase API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
require 'rubygems'
require 'json'
require 'net/http'

class Crunchbase_Company

  @record = nil

  def initialize( company )

    base_url = "http://api.crunchbase.com"
    url = "#{base_url}/v/1/company/#{company}.js"

    resp = Net::HTTP.get_response(URI.parse(url))

    @record = JSON.parse(resp.body)

  end

  def founded_year
    return @record['founded_year']
  end

  def num_employees
    return @record['number_of_employees']
  end

  def company_type
    return @record['category_code']
  end

  def people

    employees = Hash.new

    relationships = @record['relationships']

    if !relationships.nil?

        relationships.each do | person |
            if person['is_past'] == false then
                permalink = person['person']['permalink']
                title = person['title']
                employees[permalink] = title
            end
        end

    end

    return employees

  end

end




为  中所讨论的 Company 类提供了一个类似的函数。initialize 构造函数以同样的方式进行操作,而且对于提取给定的 Person(从他或她的永久链接中)名称,您拥有两种简单方法。companies 方法迭代用于 relationships 密钥的散列,并将该特定个人过去与之关联的公司(企业)返回,在这种情况下,关联的企业作为一种简单的(永久链接的)Ruby 数组返回。
清单 4. Person 名称空间 (person.rb) 的 Ruby CrunchBase API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
require 'rubygems'
require 'json'
require 'net/http'

class Crunchbase_Person

  @record = nil

  def initialize( person )

    base_url = "http://api.crunchbase.com"
    url = "#{base_url}/v/1/person/#{person}.js"

    resp = Net::HTTP.get_response(URI.parse(url))

    @record = JSON.parse(resp.body)

  end

  def fname
    return @record['first_name']
  end

  def lname
    return @record['last_name']
  end

  def companies

    firms = Array.new

    @record['relationships'].each do | firm |

        firms << firm['firm']['permalink']

    end

    return firms

  end

end




请注意,在这两个简单的类中,Ruby 隐藏了处理 Net::HTTP 类中的 HTTP 服务器的复杂性。解析 JSON 响应的复杂性已通过 JSON gem 完全简化。现在,让我们来考虑使用这些 API 中的一对应用程序来演示其用法。
返回列表