平臺技術(shù)-API批量調(diào)用簡介
1、為什么要批量調(diào)用
可以提高應用性能,更快的響應
比如做一個頁面需要調(diào)用7個不同的HSF服務拉取數(shù)據(jù),然后渲染頁面。這種情況下, 如想加快頁面響應,可能會考慮并發(fā)發(fā)起7次HSF調(diào)用等到數(shù)據(jù)都返回來再進行頁面渲染。但是這樣的編程模型對于調(diào)用者來說響應時間會比較長且調(diào)用繁瑣,如果TOP把7次的HSF調(diào)用通過內(nèi)部串行方式由TOP直接來完成,1次調(diào)用返回多個數(shù)據(jù)結(jié)果,那則可以大大提高每次請求響應時間。那對于某些復雜的API調(diào)用(單次調(diào)用RT可能會達到100MS的業(yè)務),那么就有很好的優(yōu)化效果
使用更少的流量
單次API調(diào)用會傳重復的系統(tǒng)或者業(yè)務入?yún)?,比如:sign、method、時間戳、fileds等參數(shù),在很多情況下這些重復參數(shù)占用了請求體里面的大部分空間。API批量調(diào)用可以將這些參數(shù)在協(xié)議層面上進行合并,實現(xiàn)參數(shù)的復用。對于移動端調(diào)用、服務端高并發(fā)調(diào)用中優(yōu)化網(wǎng)絡使用是很有幫助的。
2、批量調(diào)用API特性
- 支持目前所有安全和業(yè)務特性
- 支持除文件上傳外的所有API自由組合調(diào)用
- 支持多session混合調(diào)用
- 調(diào)用結(jié)果互不干擾
- API響應順序和請求順序完全一致,無需排序或按編號查詢結(jié)果
- 極速體驗,M次交易API+N次商品API調(diào)用,RT約為1次交易API調(diào)用(假設交易API RT> 商品API)
- Servlet、HSF、HTTP混合全異步化調(diào)用模式,平穩(wěn)支撐低RT + 高RT混合場景,提高服務端吞吐能力
- 公共參數(shù)和方法名稱可進行合并,精簡請求報文
- 簡單的調(diào)用協(xié)議,不用SDK也能快速實現(xiàn)批量API調(diào)用
3、批量調(diào)用技術(shù)簡介
3.1 協(xié)議內(nèi)容
請求URL:
http://gw.api.taobao.com/router/batchPOST:
PAYLOAD:
- Payload以from的形式去承載每個API,默認以\r\n-S-\r\n進行分割;參數(shù)值需要進行URL Encode
- 自定義分隔符方式:httpHeader.put(“top-api-separator”,”????”)
- 第一行#PUBLIC#開始,可提取公共參數(shù)和API名稱,為可選。如不需要提取公共參數(shù),同時去掉#PUBLIC#行和第一個分隔符
- 參數(shù)優(yōu)先級:API行參數(shù) ===覆蓋===> #PUBLIC#參數(shù) ===覆蓋===> URL參數(shù)
- 簽名方式,類似于rest簽名:hmac(其他類似) byte2hex (hmac(key1value1key2value2...payloadsecret))
- 占位符:假設你把一個API的所有參數(shù)都抽象到了#PUBLIC#區(qū)域,請放入一個占位符N,標示我其實是一個API;如上所示
3.2 協(xié)議內(nèi)容-響應
Response:情況1
Response:情況2
-S-
{"time_get_response":{"time":"2016-01-05 10:53:02","request_id":"16t6sm2gxmm5q"}}
-S-
{"trade_fullinfo_get_response":{"trade":{"orders":{"order":[{"adjust_fee":"0.00","buyer_rate":false,"cid":50069506,"consign_time":"2015-12-03 14:01:07","discount_fee":"0.00","end_time":"2015-12-03 16:18:19","invoice_no":"0000","is_oversold":false,"logistics_company":"電 子憑 證","num":1,"num_iid":2100727710059,"oid":193923500416510,"order_from":"TAOBAO","payment":"11.00","pic_path":"http:\/ \/img04.daily.taobao.net\/bao\/uploaded\/i4 \/TB1EG6SXXXXXXaBXXXXXXXXXXXX_!!0- item_pic.jpg","price":"11.00","refund_status":"NO_REFUND","seller_rate":false,"seller_type":"C","shipping_type":"virtual","snapshot_url":"d:193923500416510_1","status":"TRADE_FINISHED","title":" 測試發(fā)布收費課 2015123","total_fee":"11.00"}]},"payment":"11.00","receiver_address":"15988161275","receiver_mobile":"","receiver_name":" 不****","status":"TRADE_FINISHED","tid":193923500416510,"type":"eticket"},"request_id":"16t6sm2gxmm5q"}}
-S-
{"error_response":{"code":27,"msg":"Invalid session","sub_code":"invalid-sessionkey","request_id":"16t6sm2gxmm5q"}}
- Response,情況1:響應報文只有一條結(jié)果;比如簽名,appkey不存在;這些都是共性,比如我們只進行一次簽名,那么一條API簽名錯誤,意味著所以api都會簽名錯誤。
- Response,情況2:響應報文和請求報文里面的API個數(shù)一致,響應順序也會和請求順序保持一致。比如你提交15條請求,可能會出現(xiàn)10條成功,3條流控,2條HSF服務提供端異常;但是我們的響應體依然會有15條請求響應。
- 自定義分隔符方式:默認分隔符為\r\n-S-\r\n ;自定義方式在提交請求是,使用httpHeader.put(“top-api-separator”,”????”);請求和響應體分隔符保持一致
4 、SDK使用方式
4.1 創(chuàng)建Client
”, “appkey”,“secret");} //注:使用該方式,需要下載最新的sdk,老的sdk暫未支持批量調(diào)用功能
4.2 創(chuàng)建BatchRequest
4.3 添加請求API
.addRequest(timeGetRequest2)
.addRequest(timeGetRequest3)
.addRequest(timeGetRequest4)
.addRequest(fullinfosRequest1)
.addRequest(fullinfosRequest2)
.addRequest(fullinfosRequest3);
4.4 提交請求
4.5 遍歷結(jié)果
for (int i = 0; i < response.getResponseList().size(); i++)
println("body:" + response.getResponseList().get(i).getBody());
}
4.6 隨機查詢結(jié)果
TimeGetResponse resp1 = response.getResponse(timeGetRequest1);
if(timeGetResponse1.isSuccess())
println(“服務器時間:" + resp1.getTime());
TradeFullinfoGetResponse rep2 = response.getResponse(fullinfosRequest3);
}
注:使用sdk實現(xiàn)批量api調(diào)用功能 ,需要下載最新的sdk,sdk下載及使用點 這里 。
5、典型使用場景舉例
以調(diào)用接口獲取訂單詳情為例,原來要查詢某個商家多個訂單詳情,需要重復發(fā)起多次請求;現(xiàn)如果使用批量方式調(diào)用,1次請求就可以返回多個結(jié)果,可以大大提高API調(diào)用效率。以下是常用使用場景sdk調(diào)用示例(java):
5.1、查詢單個商家多個訂單詳情
TradeFullinfoGetRequest req1 = new TradeFullinfoGetRequest();
req1.setFields( "tid");
req1.setTid(6666666666661L); //訂單1
TradeFullinfoGetRequest req2 = new TradeFullinfoGetRequest();
req2.setFields( "tid");
req2.setTid(6666666666662L); //訂單2
TaobaoBatchRequest req = new TaobaoBatchRequest();
req.addRequest(req1);
req.addRequest(req2);
TaobaoBatchResponse rsp = client.execute(req, "test"); //test表示商家的sessionkey
5.2、查詢多個商家多個訂單詳情
TradeFullinfoGetRequest req1 = new TradeFullinfoGetRequest();
req1.setFields( "tid");
req1.setTid(6666666666661L); //商家a的訂單1
TradeFullinfoGetRequest req2 = new TradeFullinfoGetRequest();
req2.setFields( "tid");
req2.setTid(6666666666662L); //商家a的訂單2
TradeFullinfoGetRequest req3 = new TradeFullinfoGetRequest();
req3.setFields( "tid");
req3.setTid(8888888888881L); //商家b的訂單1
req3.setBatchApiSession( "testtest"); //商家b的sessionkey
TaobaoBatchRequest req = new TaobaoBatchRequest();
req.addRequest(req1);
req.addRequest(req2);
req.addRequest(req3);
TaobaoBatchResponse rsp = client.execute(req, "test"); //商家a的sessionkey
5.3、查詢多個商家訂單和商品詳情
TradeFullinfoGetRequest req1 = new TradeFullinfoGetRequest();
req1.setFields( "tid");
req1.setTid(6666666666661L); //商家a的訂單1
TradeFullinfoGetRequest req2 = new TradeFullinfoGetRequest();
req2.setFields( "tid");
req2.setTid(6666666666662L); //商家a的訂單2
ItemSellerGetRequest req3 = new ItemSellerGetRequest();
req3.setFields( "num_iid");
req3.setNumIid(8888888881L); //商家b的商品1
req3.setBatchApiSession( "testtest"); //商家b的sessionkey
TaobaoBatchRequest req = new TaobaoBatchRequest();
req.addRequest(req1);
req.addRequest(req2);
req.addRequest(req3);
TaobaoBatchResponse rsp = client.execute(req, "test"); //商家a的sessionkey
FAQ
測試環(huán)境下與正式環(huán)境下的API調(diào)用量有限制嗎?