仅备忘:
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构势在必行。
u 单一应用架构
Ø 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
u 垂直应用架构
Ø 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
u 分布式服务架构
Ø 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
本规范旨在为公司各业务系统之间业务复用及整合的API提供接口调用与交互规范。同时,也作为未来公司业务系统内各应用模块之间以及各业务系统之间,基于面向服务的架构,以服务接口的方式,提供数据和各种功能的一种尝试。
本规范仅适用于由服务器端发起调用请求、POST提交数据以及GET请求文本数据结果的API,统一采用UTF-8编码规则,采用JSON格式响应。
1.
2.
3.
4.
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方式。
1.
2.
3.
4.
4.1.
4.2.
以下参数是由API平台系统定义的,各系统需要支持这些参数以便接入该平台提供开放接口。API平台系统采用应用授权认证接口方式,合作初始API平台系统代第三方系统申请应用分配accessid和密钥accesskey。
API系统级参数
参数名 |
类型 |
是否必需 |
描述 |
accessid |
string |
是 |
注册应用时分配到的应用唯一标识,由系统自动生成 |
sign |
string |
是 |
参数签名,对sign外所有参数串的签名,包括应用级的参数。 |
timestamp |
long |
是 |
当前时间戳,即从1970年1月1日0时0分0秒开始所经过的秒数。同个应用的不同api请求的time值应该是递增的, 用于防replay攻击。 |
各业务系统应遵守API平台系统规范中应用级通用参数的约定。
应用级参数的通用约定
参数名 |
类型 |
描述 |
pageno |
int |
用于支持分页的api,默认为1,表示第几页 |
pagesize |
int |
用于支持分页的api,表示每页返回多少条数据,默认以及上限为25 |
Ø 过程描述
发送方将参数等进行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编码。
static void Main(string[] args)
{
string accessid = "1234";
string accesskey ="YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY";
string time =System.DateTime.Now.ToString("yyyyMMddHHmmss");
string value = "";
string queryString = "";
//准备参数
SortedDictionary
paramlist.Add("city","1");
paramlist.Add("countyName","海淀区");
paramlist.Add("buildName", "新浪大厦");
paramlist.Add("status","2");
paramlist.Add("timestamp",timestamp);
//拼接字符串
foreach (KeyValuePair
{
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编码,如果编码方式不一致则计算出来的签名会校验失败。
1.
2.
3.
4.
5.
API当前仅支持JSON响应格式,正常响应包符合如下规范的json字符串:
l http响应头中的Content-Type指定为application/json, charset=utf-8
l 字符串编码格式是UTF-8
l 输出格式为:
{
"StatusCode": "错误码(数值型)",
"StatusMsg": "错误描述(字符型)"
,
[Response Body]
}
(*) [Response Body] 可为空。
错误响应输出内容符合以下规范:
l 返回内容包含在json输出格式”Status”中,由StatusCode、StatusMsg这2个属性组成,分别用于描述错误码以及错误信息。
以下为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"
}
}
API平台系统API调用过程中可能会返回的错误码定义如下表所示:
statuscode |
statusmsg |
Description |
0 |
Success |
成功 |
1 |
Unknown error |
未知错误 |
注:错误码随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]签名算法调整,待修改示例代码