灵长科技API管理平台接入方法说明

灵长科技API管理平台接入说明

1. 概述

    1.1 总体介绍

    1.2 客户端接入方法

2. API描述范例

3. API文档规范

1. 概述

1.1 总体介绍

灵长科技API管理解决方案的核心技术是具备中美知识产权保护的,名为通用设备互联框架(CDIF)的云端应用开发管理软件框架。CDIF可为各类云端应用提供了统一的开发、管理和调用机制。客户端app可通过CDIF提供的统一JSON API调用接口访问由CDIF帮助管理的各类云端后台应用。 CDIF为云端应用提供的统一访问JSON API接口类似于经典的SOAP协议,本质上是HTTP上的RPC(远程过程调用)接口。其调用参数和返回结果全部在HTTP body中传输,安全性比普通的REST API更好,也更容易组织出复杂的API参数请求。同时,通过CDIF提供的JSON API接口,客户端app可获取一份描述某个云端应用包含的服务列表,以及每个服务下包含的所有API信息的JSON文档,该JSON文档由虚拟设备根据CDIF定义的API文档规范生成。文档中包含了所有关于如何调用虚拟设备API接口的信息。客户端app收到该文档后可对其解析、自动生成UI上的相应输入表单;并在收集到用户的输入信息后,调用CDIF的REST接口以访问该虚拟API设备。

CDIF框架代码用node.js书写,底层的云端应用代码全部使用node.js的npm包进行管理。在CDIF的定义中,云端应用使用“设备”这个名称作为应用的基本单位抽象。而每个设备都由各自的npm包中的代码管理。而这些代码的基本框架可以在灵长科技的网站上从上述的API规范自动生成,并在灵长科技网站上在线编辑和发布。云端应用及其提供的API的内部实现可以依赖于node.js丰富的生态中任意一个优秀的第三方包帮助实现,比如request, lodash, moment等等,因此非常容易开发和管理。在用户部署自己的云端应用时,灵长科技网站会自动将这些依赖包安装和部署到网站后台的CDIF应用管理框架中。云端应用可享受到一键部署升级等方便的能力。CDIF为每个虚拟设备生成唯一的device-UUID并进行管理,虚拟设备的device-UUID可通过API市场或者用户自己的私有设备列表查看,也可以由用户在控制台中,将API添加到我的API列表后,通过下面1.2.4节中描述的device-list接口获取。

1.2 客户端app接入方法

在访问CDIF提供的API接口时,客户端需要在HTTP请求的header中填入自己在灵长科技网站注册后获得的appKey。此appKey作为客户接入的唯一凭证。其具体格式为:

X-Apemesh-Key: <用户appKey>

CDIF统一提供了以下三条REST接口用于访问灵长科技API市场中的任意一个API虚拟设备,并通过这三条REST接口帮助实现客户端app对API的手动或自动化接入:

以上的get-spec接口返回虚拟设备的API描述JSON文档,schema接口用于获取API参数的完整JSON schema定义,invoke-action则用于对虚拟设备发起API调用并获取返回结果。以下对其分别简要介绍。

1.2.1 invoke-action

调用虚拟设备的API接口。API调用的请求参数和返回结果包含在JSON格式的HTTP请求和响应body中。调用请求必须包含以下信息:

对invoke-action接口的调用必须在HTTP请求header上指定Content-Type: application/json。

invoke-action的调用参数和返回结果统一包含在HTTP请求body和返回结果的input和output JSON对象中。具体格式如下:

POST <APIENTRYADDRESS>/devices/<deviceID>/invoke-action
request body:
{
    "serviceID": <id>,
    "actionName": <name>,
    "input": { ... }
}

API调用的返回结果统一包含在HTTP response body的output对象中,统一为以下格式:

response body:
{
    "output": { ... }
}

以上input和outputJSON对象中的具体内容可参考灵长科技API市场中每个虚拟设备的API文档。

成功的invoke-action调用返回HTTP 200状态码。如果发生任何错误,统一返回HTTP 500 状态码,其JSON格式的HTTP response body中包含以下信息:

收到API调用请求后,CDIF将请求数据通过设备抽象层下发到虚拟设备中,由其处理后返回相应结果。

以获取好友最近发布的10条新浪微博的API为例,其接口调用curl范例如下:

curl -H "Content-Type: application/json" -H "X-Apemesh-Key: <用户appKey>" -X POST -d '{"serviceID":"urn:weibo-com:serviceID:微博","actionName":"关注微博","input":{"count": 10}}' <APIENTRYADDRESS>/devices/8014e6d8-0880-5d72-9ad2-b8703811098e/invoke-action

1.2.2 get-spec

获取虚拟设备JSON格式的API文档。该JSON文档提供SOA,即面向服务架构风格的API描述,其中包含以下信息:

关于API文档格式的进一步说明可参考下面的API描述范例和API文档规范中的内容。

1.2.3 schema

获取API参数的完整JSON schema定义。假设某虚拟设备的API描述文档中某个参数的JSON schema定义为 /foo/bar, 那么以下调用将返回该参数的完整JSON schema对象:

GET <APIENTRYADDRESS>/devices/<device-UUID>/schema/foo/bar

以上URL中schema关键字后跟随的 /foo/bar 字符串是一个JSON指针,其取值可通过上述的get-spec接口获取。举例而言,当API描述文档中某个参数类型的schema关键字取值为 /foo/bar 时,该参数的完整JSON schema定义可从上述接口中获取。具体可参考下一节的新浪微博API范例

通过以上介绍的三个REST接口,客户端app可获取虚拟API设备提供的描述文档和其中包含的JSON schema定义,在集成react-schema-form,或者angular-schema-form这样的第三方组件后,将被CDIF框架管理的API动态地展现在app UI上供用户使用。schema form组件会根据JSON schema的定义将表单渲染在UI上,并帮助收集用户的输入到数据对象中,app只需将数据对象包装在input JSON对象中,以上述的格式发给invoke-action接口即可完成调用。同时,schema form规范提供了许多选项,可供客户端精确地控制表单的生成方式。

在此基础上,当虚拟设备的API发生变化时,比如新增API、已有API的参数定义发生变化,其API文档会随之发生变化并可从get-spec接口获取。用户可以通过客户端app实时地看到变化后的接口并发起新的访问请求。

我们提供了一个基于react-schema-form的开源范例,描述了如何通过CDIF将被其管理的REST API动态地展现在客户端app UI上供用户使用,并可在底层API接口发生变化时,将变化后的接口自动展示在app UI中。关于schema form和类似技术的更多信息可参考http://schemaform.io

如果客户端app不希望采用schema form这样的技术自动生成app UI,也可以通过传统的手动方式,通过CDIF提供的REST接口将API集成进app中。灵长科技网站的API市场中对每个虚拟API设备有详细API说明文档,以帮助实现这一过程。此时,客户端app可根据灵长科技网站API市场中的API文档说明访问上述的invoke-action接口,而忽略对另两个接口的使用。

1.2.4 device-list

除上述的三条REST接口外,CDIF提供了以下接口帮助客户端app获取某个appKey添加过的所有虚拟设备列表:

该调用将返回用户某个appKey所有添加过的device UUID,以及他们的设备基本信息,调用具体格式如下:

GET <APIENTRYADDRESS>/device-list
response:
{
  device-UUID1: {...}, device-UUID2: {...}
}

该调用永远返回HTTP 200 OK状态码

2. API描述范例

本节以一个简单的新浪微博API为例,介绍CDIF为客户端app提供的API规范。以下的JSON文档描述了一个获取关注用户最新微博的API接口定义。客户端app通过CDIF的get-spec接口获取该文档后,配合上述的schema接口即可获得所有关于如何调用该API的全部信息:

 {
   "specVersion": {
     "major": 1,
     "minor": 0
   },
   "device": {
      "friendlyName": "Weibo",
      "manufacturer": "Sina Inc.",
      "manufacturerURL": "http://www.weibo.com",
      "iconList": [
        {
          "mimetype": "image/png",
          "width": 1000,
          "height": 800,
          "depth": 8,
          "url": "https://dl6vjmn951u44.cloudfront.net/assets/d7213db550a384267fcb152ed7b57c2b/images/weibo.png"
        }
      ],
      "serviceList": {
        "urn:weibo-com:serviceID:微博": {
          "actionList": {
            "关注微博": {
              "argumentList": {
                "input": {
                  "direction": "in",
                  "relatedStateVariable": "A_ARG_TYPE_friendsTimelineArgs"
                },
                "output": {
                  "direction": "out",
                  "relatedStateVariable": "A_ARG_TYPE_friendsTimelineResult"
                }
              }
            }
          },
          "serviceStateTable": {
            "A_ARG_TYPE_friendsTimelineArgs": {
              "dataType": "object",
              "schema": "/weibo/statuses/friendsTimelineArgs"
            },
            "A_ARG_TYPE_friendsTimelineResult": {
              "dataType": "object",
              "schema": "/weibo/statuses/friendsTimelineResult"
            }
          }
        }
      }
    }
 }

以上的JSON文档中提供的信息及其说明如下:

字段名称 取值范例 说明
specVersion { "major": 1, "minor": 0 } CDIF规范版本号,取值必须是范例中的对象
friendlyName Weibo 设备名称
manufacturer Sina Inc. 厂商名称
manufacturerURL http://www.weibo.com 厂商网址
iconList { "mimetype": "image/png", "width": 1000, "height": 800, "depth": 8, "url": "https://dl6vjmn951u44.cloudfront.net/assets/
d7213db550a384267fcb152ed7b57c2b/images/weibo.png" }
API图标信息,以及图标所在URL
serviceList 服务列表。本字段以下可包含一个到多个服务名称及其内部的API定义
urn:weibo-com:serviceID:微博 服务名称
actionList API列表。本字段下可包含一个到多个API名称及其参数定义
"关注微博" API名称
argumentList API参数列表,本字段下最多只能包含两个参数,一个名为input,表示输入参数,另一个名为output,表述返回结果
input { "direction": "in", "relatedStateVariable": "A_ARG_TYPE_friendsTimelineArgs" } 本字段下direction关键字取值为in时表示这是一个输入参数,其具体类型定义在下面serviceStateTable字段的A_ARG_TYPE_friendsTimelineArgs中定义
output { "direction": "out", "relatedStateVariable": "A_ARG_TYPE_friendsTimelineResult" } 本字段下direction关键字取值为out时表示这是一个返回结果,其具体类型定义在下面serviceStateTable字段的A_ARG_TYPE_friendsTimelineResult中定义
serviceStateTable 本字段下包含API参数的具体类型定义
dataType object 本字段取值必须是object
schema /weibo/statuses/friendsTimelineArgs 本字段提供参数的JSON schema定义。该字段的取值是一个JSON指针。在获取该指针的内容后,客户端可从以下的地址获取参数的完整JSON schema定义: GET <APIENTRYADDRESS>/devices/<device-UUID>/schema/weibo/statuses/friendsTimelineArgs

在以上范例中,访问以下地址:

GET <APIENTRYADDRESS>/devices/8014e6d8-0880-5d72-9ad2-b8703811098e/schema/weibo/statuses/friendsTimelineArgs

将返回以下的参数JSON schema定义:

{
  "type": "object",
  "properties": {
    "since_id": {
      "type": "integer"
    },
    "count": {
      "type": "integer"
    },
    "max_id": {
      "type": "integer"
    },
    "page": {
      "type": "integer"
    },
    "base_app": {
      "type": "integer"
    },
    "feature": {
      "type": "boolean"
    },
    "trim_user": {
      "type": "boolean"
    }
  },
  "additionalProperties": false
}

3. API文档规范

本节以JSON schema格式完整地描述CDIF提供的统一API规范中各个字段的详细描述。 在CDIF代码实现中,以下的JSON schema文件被用于校验所有CDIF支持的设备提供的API规范的合法性:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "title": "CDIF device root schema",
  "description": "Schema specification for CDIF device model",
  "properties": {
    "configId": {
      "type": "integer",
      "maximum": 16777216,
      "minimum": 0
    },
    "specVersion": {
      "type": "object",
      "properties": {
        "major": {
          "type": "integer",
          "enum": [
            1
          ]
        },
        "minor": {
          "type": "integer",
          "enum": [
            0
          ]
        }
      },
      "additionalProperties": false,
      "required": [
        "major",
        "minor"
      ]
    },
    "device": {
      "description": "Schema for device object",
      "type": "object",
      "properties": {
        "deviceType": {
          "type": "string",
          "pattern": "^urn\\:[ \\S]{1,64}\\:device\\:[ \\S]{1,64}\\:[0-9]{1,8}$"
        },
        "friendlyName": {
          "type": "string",
          "maxLength": 64,
          "minLength": 0
        },
        "manufacturer": {
          "type": "string",
          "maxLength": 64,
          "minLength": 0
        },
        "manufacturerURL": {
          "type": "string",
          "format": "uri"
        },
        "modelDescription": {
          "type": "string",
          "maxLength": 256,
          "minLength": 0
        },
        "modelName": {
          "type": "string",
          "maxLength": 128,
          "minLength": 0
        },
        "modelNumber": {
          "type": "string",
          "maxLength": 128,
          "minLength": 0
        },
        "serialNumber": {
          "type": "string",
          "maxLength": 128,
          "minLength": 0
        },
        "price": {
          "type": "string",
          "maxLength": 256,
          "minLength": 1
        },
        "UDN": {
          "title": "Schema for device UUID",
          "type": "string",
          "maxLength": 36,
          "minLength": 36,
          "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
        },
        "UPC": {
          "type": "string",
          "maxLength": 32,
          "minLength": 0
        },
        "userAuth": {
          "type": "boolean"
        },
        "devicePresentation": {
          "type": "boolean"
        },
        "powerIndex": {
          "type": "number",
          "minimum": 0
        },
        "iconList": {
          "type": "array",
          "maxItems": 5,
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "type": "object",
            "properties": {
              "mimetype": {
                "type": "string",
                "maxLength": 18,
                "minLength": 7,
                "pattern": "^image/[a-zA-Z0-9\\+\\.]{1,12}$"
              },
              "width": {
                "type": "integer",
                "maximum": 9999,
                "minimum": 1
              },
              "height": {
                "type": "integer",
                "maximum": 9999,
                "minimum": 1
              },
              "depth": {
                "type": "integer",
                "maximum": 99,
                "minimum": 1
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            },
            "additionalProperties": false,
            "required": [
              "mimetype",
              "width",
              "height",
              "depth",
              "url"
            ]
          }
        },
        "serviceList": {
          "type": "object",
          "maxProperties": 32,
          "minProperties": 0,
          "patternProperties": {
            "^urn\\:[\\S]{1,64}\\:serviceID\\:[\\S]{1,64}$": {
              "type": "object",
              "properties": {
                "serviceType": {
                  "type": "string",
                  "pattern": "^urn\\:[ \\S]{1,64}\\:service\\:[ \\S]{1,64}\\:[0-9]{1,8}$"
                },
                "actionList": {
                  "type": "object",
                  "maxProperties": 64,
                  "minProperties": 0,
                  "patternProperties": {
                    "^[\\S]{1,128}$": {
                      "type": "object",
                      "properties": {
                        "argumentList": {
                          "type": "object",
                          "maxProperties": 32,
                          "minProperties": 1,
                          "patternProperties": {
                            "^[\\S]{1,128}$": {
                              "type": "object",
                              "properties": {
                                "direction": {
                                  "type": "string",
                                  "enum": [
                                    "in",
                                    "out"
                                  ]
                                },
                                "retval": {
                                  "type": "boolean"
                                },
                                "relatedStateVariable": {
                                  "type": "string",
                                  "maxLength": 128,
                                  "minLength": 1
                                }
                              },
                              "required": [
                                "direction",
                                "relatedStateVariable"
                              ]
                            }
                          },
                          "additionalProperties": false
                        },
                        "realPrice": {
                          "type": "number"
                        },
                        "priceInfo": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "price": {
                                "type": "number"
                              },
                              "count": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "price",
                              "count"
                            ]
                          }
                        },
                        "freeCount": {
                          "type": "integer"
                        },
                        "apiCache": {
                          "type": "number"
                        },
                        "apiLog": {
                          "type": "boolean"
                        },
                        "fault": {
                          "type": "object",
                          "properties": {
                            "schema": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "schema"
                          ]
                        }
                      },
                      "required": [
                        "argumentList"
                      ]
                    }
                  },
                  "additionalProperties": false
                },
                "serviceStateTable": {
                  "type": "object",
                  "maxProperties": 256,
                  "minProperties": 1,
                  "patternProperties": {
                    "^[\\S]{1,128}$": {
                      "type": "object",
                      "properties": {
                        "sendEvents": {
                          "type": "boolean"
                        },
                        "dataType": {
                          "type": "string",
                          "enum": [
                            "string",
                            "boolean",
                            "integer",
                            "number",
                            "object"
                          ]
                        },
                        "schema": {
                          "type": "string"
                        },
                        "defaultValue": {
                          "type": [
                            "boolean",
                            "integer",
                            "number",
                            "string"
                          ],
                          "anyOf": [
                            {
                              "type": "string",
                              "maxLength": 1024,
                              "minLength": 1
                            },
                            {
                              "type": "boolean"
                            },
                            {
                              "type": "integer"
                            },
                            {
                              "type": "number"
                            }
                          ]
                        },
                        "allowedValueRange": {
                          "type": "object",
                          "properties": {
                            "minimum": {
                              "type": "number"
                            },
                            "maximum": {
                              "type": "number"
                            },
                            "step": {
                              "type": "number"
                            }
                          },
                          "additionalProperties": false,
                          "required": [
                            "minimum",
                            "maximum"
                          ]
                        },
                        "allowedValueList": {
                          "type": "array",
                          "maxItems": 256,
                          "minItems": 1,
                          "uniqueItems": true,
                          "items": {
                            "oneOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              }
                            ]
                          }
                        }
                      },
                      "required": [
                        "dataType"
                      ]
                    }
                  },
                  "additionalProperties": false
                }
              },
              "required": [
                "actionList",
                "serviceStateTable"
              ]
            }
          },
          "additionalProperties": false
        },
        "deviceList": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "$ref": "#/properties/device"
          }
        }
      },
      "required": [
        "friendlyName",
        "manufacturer",
        "modelDescription"
      ]
    }
  },
  "additionalProperties": false,
  "required": [
    "specVersion",
    "device"
  ]
}

4. 文档更新记录

Revision Author Description Date
0.1 Miaobo Chen Initial draft Nov 7, 2016
0.2 Miaobo Chen text and spec update Oct 5, 2017