仅备忘:
1. 第一章 概述
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构势在必行。
u 单一应用架构
Ø 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
u 垂直应用架构
Ø 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
u 分布式服务架构
Ø 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
2. 第二章 目的
本规范旨在为公司各业务系统之间业务复用及整合的API提供接口调用与交互规范。同时,也作为未来公司业务系统内各应用模块之间以及各业务系统之间,基于面向服务的架构,以服务接口的方式,提供数据和各种功能的一种尝试。
3. 第三章 规范适用对象说明
本规范仅适用于由服务器端发起调用请求、POST提交数据以及GET请求文本数据结果的API,统一采用UTF-8编码规则,采用JSON格式响应。
4. 第四章 请求数据包格式规范
4.1.URL
API 服务接口提供如下REST风格的HTTP接口:
http://api.xxx.com/yyy/zzz?{query_string}
query_string由系统级参数部分和具体API调用参数部分组成,以key1=value1&key2=value2&…表示,对于采用POST请求的Open API,query_string部分则是在POST请求体里。所有查询类的API接口既支持POST,也支持GET方式,提交类的API接口仅支持POST方式。
4.2.参数
4.2.1. 系统级参数约定
以下参数是由API平台系统定义的,各系统需要支持这些参数以便接入该平台提供开放接口。API平台系统采用应用授权认证接口方式,合作初始API平台系统代第三方系统申请应用分配accessid和密钥accesskey。
API系统级参数
参数名 | 类型 | 是否必需 | 描述 |
accessid | string | 是 | 注册应用时分配到的应用唯一标识,由系统自动生成 |
sign | string | 是 | 参数签名,对sign外所有参数串的签名,包括应用级的参数。 |
timestamp | long | 是 | 当前时间戳,即从1970年1月1日0时0分0秒开始所经过的秒数。同个应用的不同api请求的time值应该是递增的, 用于防replay攻击。 |
4.2.2. 应用级参数的通用约定
各业务系统应遵守API平台系统规范中应用级通用参数的约定。
应用级参数的通用约定
参数名 | 类型 | 描述 |
pageno | int | 用于支持分页的api,默认为1,表示第几页 |
pagesize | int | 用于支持分页的api,表示每页返回多少条数据,默认以及上限为25 |
4.2.3. 参数签名算法
Ø 过程描述
发送方将参数等进行HMAC算法计算,将得到的哈希值(即签名值)与请求的参数一同提交至接收方,然后接收方再次将参数等值进行HMAC算法计算,将得到的哈希值与你传递过来的哈希值进行核对验证,若一样,说明请求正确、验证通过,进行一下步工作,若不一样,将返回错误。
以如下请求为例,说明sign签名的生成步骤:
http:// api.xxx.com/yyy/zzz?accessid=1234&uid=abc&time=1361431471&sign=XXXXXX
Ø 步骤一:构造源串
1. 将除”sign”以外的所有请求参数按key进行字典升序排列,将除Host标头(域名
+端口)外的apiname和排序后的参数(key=value)用&拼接起来,如:
/yyy/zzz?accessid=1234&uid=abc&time=1361431471
注意:如果请求中没有apiname,则在生成签名时,不需要加入apiname。如上示例,
可改为:accessid=1234&uid=abc&time=1361431471
2. 将上述生成的字符串进行URL编码(参见本章节最后URL编码注意事项,否则容
易导致后面签名不能通过验证)。
步骤二:生成sign值
1. 使用HMAC-SHA1加密算法,将accessid对应的私钥accesskey作为参数,对从
步骤一得到的源串进行加密;
2.将上述加密后的字符串进行Base64编码。
注意:生成的签名中可能包含“=”,因此需要再进行一次URL编码。
执行完上述步骤,即可获得签名串,作为sign的值。
URL编码注意事项
URL编码规则:
签名验证时,要求对字符串中除了“-”、“_”、“.”之外的所有非字母数字字符都替换成百分号(%)后跟两位十六进制数。
十六进制数中字母必须为大写。
注意事项:
1. 某些系统方法,例如.NET系统方法HttpUtility.UrlEncode会将‘=’编码成‘%3d’,而不是%3D,导致加密签名通不过验证。Java早期版本中,调用java.net.URLEncoder下的方法进行URL编码时,某些特殊字符如“*”不会被编码,而不是“%2A”,会导致生成的签名不能通过验证。因此,需开发人员手动编码,否则将导致加密签名一直通不过验证。
2. 某些语言的urlencode方法会把“空格”编码为“+”,实际上应该编码为“%20”。这也将生成错误的签名,导致签名通不过验证。请开发人员手动将“+”替换为“%20”。
在PHP中,推荐用rawurlencode方法进行URL编码。
4.2.4. 调用示例
static void Main(string[] args)
{
string accessid = "1234";
string accesskey ="YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY";
string time =System.DateTime.Now.ToString("yyyyMMddHHmmss");
string value = "";
string queryString = "";
//准备参数
SortedDictionary<string, string>paramlist = new SortedDictionary<string, string>();
paramlist.Add("city","1");
paramlist.Add("countyName","海淀区");
paramlist.Add("buildName", "新浪大厦");
paramlist.Add("status","2");
paramlist.Add("timestamp",timestamp);
//拼接字符串
foreach (KeyValuePair<string, string>kvp in paramlist)
{
value += kvp.Key + kvp.Value;
queryString += "&" +kvp.Key + "=" + Utf8Encode(kvp.Value);
}
StringBuilder sb = new StringBuilder();
sb.Append(apiKey);
sb.Append(value);
sb.Append(apiSecret);
value = sb.ToString();
string url ="http://api.xxx.com/build/getbuildinfo?apikey=" + apiKey +"×tamp=" + timestamp + "&apisign=" +SHA1(value) + queryString;
int status = 0;
Console.WriteLine(url);
Console.WriteLine(RequestUrl(url, outstatus));
Console.ReadLine();
}
执行结果显示如下(仅演示,中间略过RequestUrl(url, out status)具体执行):[a1]
注意:请确保接口与调用者的字符串编码一致,最好统一使用utf-8编码,如果编码方式不一致则计算出来的签名会校验失败。
5. 第五章 响应数据包格式规范
5.1. Json输出格式
API当前仅支持JSON响应格式,正常响应包符合如下规范的json字符串:
l http响应头中的Content-Type指定为application/json, charset=utf-8
l 字符串编码格式是UTF-8
l 输出格式为:
{
"StatusCode": "错误码(数值型)",
"StatusMsg": "错误描述(字符型)"
,
[Response Body]
}
(*) [Response Body] 可为空。
5.2. 错误响应输出格式
错误响应输出内容符合以下规范:
l 返回内容包含在json输出格式”Status”中,由StatusCode、StatusMsg这2个属性组成,分别用于描述错误码以及错误信息。
5.3. 输出格式示例
以下为json输出格式示例:
{
"StatusCode": 0,
"StatusMsg": "Success"
,
"Body": {
"ID": 2,
"Name": "新浪大厦",
"Description": {
"CityName": "北京",
"CountyName": "海淀",
"Business": "中关村",
"Address": "中关村大街甲59号文化大厦1007"
},
"Fit": "豪装",
"AvgDailyRent": 500,
"MainImage": "http://192.168.1.1:7000/LP/2015/09/14/Tb/20150914163059_6404.jpg"
}
}
6. 第六章 错误码定义
API平台系统API调用过程中可能会返回的错误码定义如下表所示:
statuscode | statusmsg | Description |
0 | Success | 成功 |
1 | Unknown error | 未知错误 |
注:错误码随API细化,会逐渐增多,当前为规则说明。
7. 第七章 API接口细则
以下为API接口细则参考:
服务名称 | |||||
| |||||
HTTP访问方式 | |||||
GET | |||||
功能描述 | |||||
获取单个课程信息 | |||||
适用对象 | |||||
所有用户,但需要提供签名校验 | |||||
注意事项 | |||||
| |||||
调用参数 | |||||
| 系统参数 | ||||
| 名称 | 类型 | 是否必须 | 描述 | |
| accessid | string | Y | 平台为应用分配的应用代号 | |
| sign | string | Y | 按照签名规则(见上文)生成的签名字符串 | |
| timestamp | long | Y |
| |
| 应用级参数 | ||||
| 名称 | 类型 | 是否必须 | 描述 | |
| cid | int | Y | 课程编号 | |
调用举例 | |||||
| http://www.abc.cn/api/values? accessid=15& timestamp=13%3a34%3a49&cid=100&sign=841b6d05c041e3876a778e93a79d5e48 | ||||
返回值 | |||||
| 正常返回值格式(JSON) | ||||
| { "StatusCode": 0, "StatusMsg": "Success", "Body": { "ID": 100, "Name": "测试课程", "Description": { "SchoolName": "北京电大", "Teacher": "杨老师" }, "MainImage": "http://192.168.1.1:7000/LP/2015/09/14/Tb/20150914163059_6404.jpg" } }
| ||||
[a1]签名算法调整,待修改示例代码