1. 接口约定
1.1. 接口风格
地球号API接口风格近似KOA风格,再加上地球号自己的业务并不复杂。形成了地球号自己接口格式约定。地球号严格依照REST风格对网络资源进行增删改查详。地球号设计风格约定如下:
每个API资源必须为名词或名词意义.体现在接口的第一级单词。在某些情况下,动词也可以作为一种资源存在,如/login是指登录资源。用户登录是一种非常特殊的资源,资源名称为login,此时login被看成一个名词,表示一种登录资源。用户登录操作时POST:/login.用户密码是一种非常特殊的资源,资源名称为pass,重置密码被认作是在pass资源添加一个密码,为POST:/pass。修改密码是修改一个密码资源,为PUT:/pass/[user_id]. 注意,修改pass的时候id为用户id
每个资源接受五种基本操作:增(POST),删(DELETE),改(PUT),查(QRY),详(GET)。在系统编程里,五种操作在地球号系统程序编码为:ADD/DEL/PUT/QRY/GET。其中,QRY=GET. QRY请求时GET:/resource?filter1=value1&filter2=value2 这样的格式. QRY方式下要求path只有一级,不得有二级.例如不能又GET:/resource/resource_sub? 这样的表达
资源操作命名的时候,用PUT而不用SET, 原因就是因为REST接口用PUT,REST的PUT和POST都是创建和更新资源,PUT区分POST的地方是PUT的路径里要有资源id。在地球号内,出于对接口清晰度的管控,要求PUT必须有资源id,PUT只能修改资源,如果id对应的资源不存在,请求就会出错。
PUT和POST的区别,!参考 在更新资源的操作上,POST 和 PUT 基本相同。在创建资源时,PUT可以指定资源路径,POST无法指定资源路径。因而,PUT是幂等的操作,即重复操作不会产生变化,10次PUT 的创建请求与1次PUT的创建请求相同,只会创建一个资源,其实后面9次的请求只是对已创建资源的更新,且更新内容与原内容相同,所以不会产生变化。POST 的重复操作截然不同,10次POST请求将会创建10个资源。绝大多数的请求都可以通过POST实现,PUT 幂等的特性也可以在服务器端通过特殊处理来达到相同的效果,因而在API 设计时
幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。
1.2. 接口约束
操作 | URL方式 | 要求 |
---|---|---|
ADD | POST:/user | |
DEL | DELETE:/user/[user_id] | 没有body |
PUT | PUT:/user/[user_id] | 更新的字段必须在body |
QRY | GET:/user?filter=* | 字段是固定的,参考 |
GET | GET:/user/[user_id] |
1.3. 接口字段
地球号接口的字段有一套的规则,规定了一系列固定参数。地球号接口参数分为四部分:用户业务参数,网关常量参数,SDK参数,令牌参数
1.3.1. 用户业务参数
用户在调用API请求时发送的业务参数。
字段 | 位置 | 类型 | 说明 |
---|---|---|---|
XduaApiVersion | head | string | 接口的版本 |
XduaClientDev | head | string | 发送接口请求的设备的序列号。例如"mac:1e479fee578f"这样的字符串 |
Authorization | head | string | JWT令牌 |
action | head | string | 接口API的动作 |
[!note] 为什么action是个系统官方必须字段,却用的是小写?因为action是暴露给前端调用者的。
1.3.2. 网关常量参数
请求在经过网关时,网关自动添加的参数。主要用来辅助权限控制。
访问控制
字段 | 位置 | 样式 | 说明 |
---|---|---|---|
XduaApiColor | head | X/R/G/B | API要求的令牌颜色。 XRGB允许司中颜色令牌与或者*允许所有颜色的令牌。 |
XduaApiTokenType | head | A/U | API要求的令牌类型,A代表app是应用令牌,U代表usr是用户令牌。 |
XduaApiAudience | head | aHEVYhE1 | API要求的令牌受牌方,例如,社区(zone)操作的API要求令牌的持有者(aud字段)必须是"aHEVYhE1"这个应用app_id |
XduaApiSubject | head | AnoNymuS | API要求的令牌订阅者,地球号的所有算法服务,数据服务,登录服务,验码服务API要求令牌必须是匿名令牌。地球号的平台服务要求令牌不能是匿名令牌。 |
XduaApiShop | head | XdUaXduA | API要求的令牌店铺必须是哪些店铺。 |
XduaApiAllowedRoles | head | Root,God | API允许访问者的角色列表,半角逗号隔开。有些系统服务要求必须是Root,God才可以操作。 |
XduaApiAllowedActions | head | CreateZone | 接口允许的动作列表,半角逗号隔开 |
XduaApiHttpSchema | head | HTTP/HTTPS | API要求访问的协议类型,因为网关传来的是大写,所以必须大写。 |
提供信息
[!note] 这些字段不是做访问控制,而是给后端提供良好的信息。用来日志和分析。
字段 | 位置 | 样式 | 说明 |
---|---|---|---|
XduaApiResource | head | login | API要操作的地球号资源名称。地球号里所有API都可以归类成对资源的操作,例如登录login就是一种资源。 |
XduaApiKparam | head | by+/+ustr | API接口关键参数提取模板。提取关键参数用来存放到日志表里。 |
1.3.3. SDK参数参数
API请求调用时,SDK自动添加的参数。这些参数对统计,分析,定位
字段 | 位置 | 类型 | 说明 |
---|---|---|---|
CaClientIp | head | string | 客户端的IP |
CaClientUa | head | string | 客户端的UserAgent |
CaDomain | head | string | 客户端的域名 |
CaRequestHandleTime | head | string | 请求经过网关时的Unix时间。如果后端需要对请求进行时间戳校验,可以在 API 定义中选择系统参数 “CaRequestHandleTime” ,值为网关收到请求的格林威治时间。 |
CaAppId | head | string | API授权的应用ID。例如'6151834' |
CaRequestId | head | string | API请求的ID。例如6079D3AC-93F8-4297-8853-3CAAAA14044F |
CaApiName | head | string | API在网关控制台的名字。AddLogin |
CaHttpSchema | head | string | API的协议。必须是大写HTTP 或者HTTPS |
CaProxy | head | string | 'AliCloudAPIGateway' |
CaCloudMarketInstanceId | head | string | 这个参数不是必须的,在后端不做必须性检查。似乎,只有上了云市场才有这个参数 |
1.3.4. 令牌参数
API请求调用时,SDK自动添加的参数。这些参数对统计,分析,定位
字段 | 位置 | 类型 | 说明 |
---|---|---|---|
CaClientIp | head | string | 客户端的IP |
CaClientUa | head | string | 客户端的UserAgent |
CaDomain | head | string | 客户端的域名 |
CaRequestHandleTime | head | string | 请求经过网关时的Unix时间。如果后端需要对请求进行时间戳校验,可以在 API 定义中选择系统参数 “CaRequestHandleTime” ,值为网关收到请求的格林威治时间。 |
CaAppId | head | string | API授权的应用ID。例如'6151834' |
CaRequestId | head | string | API请求的ID。例如6079D3AC-93F8-4297-8853-3CAAAA14044F |
CaApiName | head | string | API在网关控制台的名字。AddLogin |
CaHttpSchema | head | string | API的协议。必须是大写HTTP 或者HTTPS |
CaProxy | head | string | 'AliCloudAPIGateway' |
CaCloudMarketInstanceId | head | string | 这个参数不是必须的,在后端不做必须性检查。似乎,只有上了云市场才有这个参数 |
1.4. 接口ACTION字段
所有接口,都存在一个字段:action,这个字段其实是对接口的附加约定,指定了接口的额外操作,这个操作有以下意义,对查询出来的接口做什么操作,这个字段有默认值,默认值和接口字串一致。
- POST里,action放在query里
- GET 里,action放在query里
- QRY 里,action放在query里
- DEL 里,action放在query里
- PUT 里,action放在query里
这里为什么不同的请求,action都放在query字段,这是为了方便我们做接口。
1.5. QRY接口标准
GET:http://api.xdua.com/resource?
在地球号设计里QRY接口是个特别的接口,其接口是固定的,针对任何资源都是一样的。
字段名 | 位置 | 类型 | 说明 | 描述 | 可选 |
---|---|---|---|---|---|
apiv | head | string | API版本,默认是1.0.0 | 1.0.0 | 可选 |
Authorization | head | string | 客户端保存的鉴权token | Authorization字符串 | 必选 |
action | query | string | 接口动作 | 16个字符以内 | 可选 |
where | query | String | 查询条件 | 查询条件 | 这是一个json字符串做了urlencode后的结果 |
filter | query | String | 过滤类别 | 查询条件 | 这是一个json字符串做了urlencode后的结果 |
offset | query | int | 搜索开始的偏移条件 | 获取授权的开始个数,若不设置默认为0 | 可选 |
limit | query | int | 搜索数量 | 获取授权的数量,若不设置默认为20 | 可选 |
page | query | int | 搜索页号 | 如果page存在的话,就可以忽略offset的效果,和limit一起使用。使用page搜索 | 可选 |
order | query | String | 顺序 | 必须按照"字段:ASC/DESC"方式书写,如 name:DESC,默认的order是inc:DESC | 可选 |
为什么where不用base64, Base64 可以将二进制转码成可见字符方便进行http传输,但是base64转码时会生成“+”,“/”,“=”这些被URL进行转码的特殊字符,导致两方面数据不一致。 客户端向服务器传递参数时,参数中的“+”全部变成了空格,原因是URL中默认的将“+”号转义了。所以要用urlencode
1.5.1. 接口反馈格式
地球号接口设计严格按照API网关要求,分为Path参数,Query参数,Body参数. 请求头里的Authorization字段放置token或签名.
1.5.2. 地球号接口返回数据格式
//status=0时,表示成功,reason是Success或success. result字段是以字典放置key和value的方式放置结果数据. debug字段字典以key:value方式放置调试信息,这些信息用于api开发者自己查看,不应该暴露给普通用户.
{
error:0,
reason: 'Success',
result:{ key1:value1,key2:value2,key3:value3 },
debug: { key1:value1,key2:value2},
}
//qry请求的result是{"list":[],"maxpage":12}这种结构,其中list是查询出来的列表,maxpage是当前查询套件对应的最大页数.
//status=1时,表示失败,reason是字符串格式失败原因. result以字典方式放置一些各接口可能用到的结果数据. debug字段字典以key:value方式放置调试信息,这些信息用于api开发者自己查看,不应该暴露给普通用户.
{
error:0,
reason: 'AppNotExisted',
result:{ key1:value1,key2:value2,key3:value3 },
debug: { key1:value1,key2:value2},
}
在设计原则上, result和debug必须是字典,不应该是数组.