构建客户端库

简介

您可以使用 Google API Discovery Service 构建与 Google API 搭配使用的各种不同工具。不过,发现文档的主要用途是让 Google 使用各种编程语言创建客户端库。本部分介绍如何为 Google API 构建自定义客户端库。

稳定且功能完整的客户端库是一种复杂的工具,可能需要数月的时间才能完成开发。不过,为 Google API 构建简单客户端库的一般说明可分为三个简单步骤:

  1. 提取发现文档并构建 API Surface
  2. 编写请求
  3. 拨打电话并获取响应

下面几部分更详细地介绍了这些步骤。您也可以参阅“示例”部分中的简单 API 客户端示例,了解这些说明与代码之间的对应关系。

第 1 步:提取发现文档

在开始实现客户端库之前,有一些基本要求会影响您的开发路径。例如,您选择的编程语言可能是类型化的或非类型化的,如果是输入的,它可以是静态类型,也可以是动态类型。它可以编译或解释。这些要求将指导您如何使用和使用探索文档。

第一个开发任务是提取发现文档。至于提取文档的准确策略,取决于您确定的要求。例如,对于静态类型的语言,您可以在该过程的早期阶段提取发现文档,然后生成代码以处理发现文档描述的特定 API。对于强类型语言,您可以生成一些代码并构建已编译的库。对于动态类型的语言,您可以在使用编程接口时延迟构建编程结构,以动态连接到 API。

第 2 步:编写请求

编写请求涉及两个单独的步骤:

  1. 编写请求正文。
  2. 构建请求网址。

您需要将请求正文(如果有)从适合语言的表示法转换为正确的传输格式。例如,在 Java 客户端库中,每种类型的请求都可能存在一个类,该类允许对请求数据进行类型安全的处理,并能够序列化为 JSON 格式。

请求网址的构建略微复杂一些。

API 中每个方法的 path 属性都使用 URI 模板 v04 语法。此属性可以包含用大括号括起来的变量。下面是一个包含变量的 path 属性示例:

/example/path/var

在上述路径中,var 是一个变量。此变量的值来自该方法的发现文档 parameters 部分。每个变量名称在 parameters 对象中都有一个对应的值。在上面的示例中,parameters 部分有一个名为 var 的参数(其 location 属性为 path,表示它是一个路径变量)。

发出请求时,您应将 var 的值替换成网址。例如,如果库的用户选择将 var 设置为值 foo,则新网址将为 /example/path/foo

另请注意,path 属性是一个相对 URI。如需计算绝对 URI,请按以下步骤操作:

  1. 从发现文档的顶层获取 rootUrl 属性。
    例如,Google Cloud Service Management API发现文档中的 rootUrl 属性为:

    https://servicemanagement.googleapis.com/

  2. 从发现文档的顶层获取 servicePath
    例如,Google Cloud Service Management API 的发现文档中的 servicePath 属性为空。

  3. 将它们连接在一起即可获得:

    https://servicemanagement.googleapis.com/

  4. 获取 path 属性,将其展开为 URI 模板,并将该扩展的结果与上一步中的 URI 合并。
    例如,在 Google Cloud Service Management API 的 get 服务方法中,path 属性的值为 v1/services/{serviceName}。因此,该方法的完整 URI 为:

    https://servicemanagement.googleapis.com/v1/services/{serviceName}

如需调用 Google Cloud Service Management API,必须使用 API 密钥。因此,应用 API 密钥后,用于获取 API Discovery Service 服务定义的完整 URI 如下所示:

https://servicemanagement.googleapis.com/v1/services/discovery.googleapis.com?key=API_KEY

第 3 步:拨打电话并处理响应

发送请求后,您需要将响应反序列化为相应的语言表示形式,同时注意处理可能出现的错误情况 - 包括底层 HTTP 传输和 API 服务生成的错误消息。Google JSON 样式指南中记录了错误的格式。

示例

有关使用 Google API Discovery Service 实现的客户端库和工具的一些具体示例,请参阅库和示例文档。此外,以下部分还提供了一个简单的 API 客户端库示例。

简单的 API 客户端

下面是一个用 Python3 编写的非常简单的客户端库示例。客户端会构建一个与 Google Cloud Service Management API 进行交互的接口,然后使用该接口获取 API Discovery Service 的服务定义。

警告:以下代码是典型客户端库的简化版本。我们并未完整提供该实现,以演示构建客户端库的一些方面。这不是可直接用于生产环境的代码。

import httplib2
import json
import uritemplate
import urllib

# Step 1: Fetch Discovery document
DISCOVERY_URI = "https://servicemanagement.googleapis.com/$discovery/rest?version=v1"
h = httplib2.Http()
resp, content = h.request(DISCOVERY_URI)
discovery = json.loads(content)

# Step 2.a: Construct base URI
BASE_URL = discovery['rootUrl'] + discovery['servicePath']

class Collection(object): pass

def createNewMethod(name, method):
  # Step 2.b Compose request
  def newMethod(**kwargs):
    body = kwargs.pop('body', None)
    url = urllib.parse.urljoin(BASE_URL, uritemplate.expand(method['path'], kwargs))
    for pname, pconfig in method.get('parameters', {}).items():
      if pconfig['location'] == 'path' and pname in kwargs:
        del kwargs[pname]
    if kwargs:
      url = url + '?' + urllib.parse.urlencode(kwargs)
    return h.request(url, method=method['httpMethod'], body=body,
                     headers={'content-type': 'application/json'})

  return newMethod

# Step 3.a: Build client surface
def build(discovery, collection):
  for name, resource in discovery.get('resources', {}).items():
    setattr(collection, name, build(resource, Collection()))
  for name, method in discovery.get('methods', {}).items():
    setattr(collection, name, createNewMethod(name, method))
  return collection

# Step 3.b: Use the client
service = build(discovery, Collection())
print (service.services.get(serviceName='discovery.googleapis.com', key='API_KEY'))

客户端的主要组件为:

  • 第 1 步:提取发现文档
    系统会检索 Google Cloud Service Management API 的发现文档,并将其解析为数据结构。由于 Python 是动态类型语言,因此可以在运行时提取发现文档。
  • 第 2.a 步:构建基本 URI
    计算基准 URI。
  • 第 2.b 步:编写请求
    对集合调用方法时,系统会使用传入该方法的参数来扩展 URI 模板,并将位置为 query 的参数放入网址的查询参数中。最后,系统会使用发现文档中指定的 HTTP 方法向组合网址发送请求。
  • 第 3.a 步:构建客户端界面
    客户端 Surface 以递归方式在解析后的发现文档之上构建。对于 methods 部分中的每个方法,新方法都会附加到 Collection 对象。由于集合可以嵌套,因此我们查找 resources,并以递归方式为其所有成员构建一个 Collection 对象(如果找到的话)。每个嵌套集合也作为一个属性附加到 Collection 对象。
  • 第 3.b 步:使用客户端
    此示例演示了如何使用构建的 API Surface。首先,根据发现文档构建服务对象,然后通过 Google Cloud Service Management API 检索 API Discovery Service 的服务定义。