平台技術-API批量呼叫簡介
1、為什麼要大量呼叫
可以提高應用效能, 一個頁面需要呼叫7個不同的HSF服務拉取數據,然後渲染頁面。這種情況下, 如想加快頁面回應,可能會考慮並發發起7次HSF調用等到資料都返回來再進行頁面渲染。但這樣的程式設計模型對於呼叫者來說回應時間會比較長且呼叫繁瑣,如果TOP把7次的HSF呼叫透過內部串列方式由TOP直接來完成,1次呼叫傳回多個資料結果,那則可以大大提高每次請求回應時間。那對於某些複雜的API呼叫(單次呼叫RT可能達到100MS的業務),那麼就有很好的優化效果
地次API呼叫會傳重複的系統或是業務入參,例如:sign、method、時間戳記、fileds等參數,在很多情況下這些重複參數佔用了請求體裡面的大部分空間。 API批次呼叫可以將這些參數在協定層級上進行合併,實現參數的複用。對於在行動端呼叫、服務端高並發呼叫中優化網路使用是很有幫助的。
2、批次呼叫API特性
- 支援目前所有安全性和業務特性
- 支援除檔案上傳外的所有API自由組合呼叫
- 支援多session混合呼叫
- 呼叫結果互不干擾
- API回應順序和請求順序完全一致,無需排序或依編號查詢結果
- 極速體驗,M次交易API N次商品API調用,RT約為1次交易API調用(假設交易API RT> 商品API)
- Servlet、HSF、HTTP混合全異步化調用模式,平穩支撐低RT 高RT混合場景,提高服務端吞吐能力
- 公共參數和方法名稱可進行合併,精簡請求報文
- 簡單的呼叫協議,不用SDK也能快速實作批次API呼叫
3、批次呼叫技術簡介
3.1 協定內容
請求網址:
http://gw.api.taobao.com/router/batchPOST:
http://gw.api.taobao.com/router/batch?sign=5336DB2C525E1A3AD1013BC82C4437B2×tamp=2016-01-05 10:15:15&v=2.0&app_key> 51625dcd2d1921ba80c6d2b43a2a5a37e7c7c73627811065
Content-Type#
:
text/plain;charset=UTF-8
PAYLOAD :
- Payload以from的形式去承載每個API,預設以\r\n-S-\r\n進行分割;參數值需要進行URL Encode
- #自訂分隔符號方式:httpHeader.put(“top-api-separator”,”????”)
- 第一行#PUBLIC#開始,可擷取公用參數和API名稱,為可選。如不需要擷取公用參數,同時去掉#PUBLIC#行與第一個分隔符號
- 參數優先權:API行參數 ===覆寫===> #PUBLIC#參數 ===覆寫= ==> URL參數
- 簽名方式,類似rest簽章:hmac(其他類似)byte2hex (hmac(key1value1key2value2...payloadsecret))
- 佔位元符:假設你把一個API的所有參數都抽像到了#PUBLIC#區域,請放入一個佔位符N,標示我其實是一個API;如上圖
3.2 協定內容-回應
Response:情況1
{"error_response":{"code":25,"msg":"Invalid signature","request_id":"16t6sm38r9709"}}
回應:情況2
{"time_get_response":{"time":"2016-01 -05 10:53:02","request_id":"16t6sm2gxmm5q"}}
-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,"num":1,"num_iid":2100727710059,"--------" order_from":"TAOBAO" ,"付款":"11.00","pic_path":"http:\/ \/img04.daily.taobao.net\/bao\/uploaded\/i4 \/TB1EGXXXXXXXXXaBXXXXXXXXX_!pic- .jpg","價格":"11.00","refund_status":"NO_REFUND","seller_rate":false,"seller_type":"C","shipping_type":"virtual","snapshot_url":" d:193923500416510_1","status": "TRADE_FINISHED","title":"測試發布收費課 2015123","total_fee":"11.00"}]}," payment":"11.00","reress" :"15988161275","receiver_mobile":"", "receiver_name":" 不****","status":"TRADE_FINISHED","tid":193923500416510,"type":"eticket"}, "request_id":"16t6sm2gxmm5q"}}
-S-
- Response,情況1:回應封包只有一個結果;例如簽名,appkey不存在;這些都是共性,例如我們只進行一次簽名,那麼一條API簽章錯誤,代表所以api都會簽章錯誤。
- Response,情況2:回應封包和請求封包裡面的API個數一致,回應順序也會和請求順序保持一致。例如你提交15條請求,可能會出現10條成功,3條流控,2條HSF服務提供端異常;但是我們的響應體依然會有15條請求回應。
- 自訂分隔符號方式:預設分隔符號為\r\n-S-\r\n ;自訂方式在提交請求是,使用httpHeader.put(“top-api-separator”,”?? ??”);請求和回應體分隔符號保持一致
4 #、SDK使用方式
4.1 建立Client
BatchTaobaoClient client = new BatchTaobaoClient (“http://gw.api.taobao.com router/batch
#”, 「appkey」,「secret");} router/batch
#」, 「appkey」,「secret");} / /註:使用該方式,需要下載最新的sdk,舊的sdk暫未支援批次呼叫功能#”, 「appkey」,「secret");} router/batch
#TaobaoBatchRequest batchRequest = new TaobaoBatchRequest();
##batchRequest.addRequest(timeGetRequest1)
.addRequest( timeGetRequest4)
.addRequest(fullinfosRequest2)
.addRequest(fullinfosRequest3);
4.4 提交請求.addRequest(fullinfosRequest2)
.addRequest(fullinfosRequest3);
if (response.isSuccess()) {
for (int i println("body:" response.getResponseList( ).get( i).getBody());
}
#############'###'}sRequest3);## #
4.6 隨機查詢結果
if (response.isSuccess()) {
Response(timeGetRequest1);
if(timeGetResponse11 .isSuccess())
TradeFullinfoGetResponse rep2 = response.getResponse(fullinfosRequest3);
}
Response(timeGetRequest1);
if(timeGetResponse11 .isSuccess())
TradeFullinfoGetResponse rep2 = response.getResponse(fullinfosRequest3);
}
附註:使用sdk實作批次api呼叫功能 ,需下載最新的sdk,sdk下載及使用點 這裡 。
5、典型使用場景舉例
以呼叫介面取得訂單詳情為例,原來要查詢某個商家多個訂單詳情,需要重複發起多次請求;現如果使用批次方式調用,1次請求就可以返回多個結果,可以大幅提高API調用效率。以下是常用使用場景sdk呼叫範例(java):
5.1、詢問單一商家多個訂單詳情
BatchTaobaoClient client = new BatchTaobaoClient ( ","test","test");
TradeFullinfoGetRequest req1 = new TradeFullinfoGetRequest();
req1.setFields( "tid");
req1.setTid(6666666666661L); //訂單1
TradeFullinfoGetRequest req2 = "tid");
req2.setTid(66666666666622
TaobaoBatchRequest req = new TaobaoBatchRequest();
req.addRequest(req1);
TaobaoBatchResponse rsp = client.execute(req, 的sessionkey
TradeFullinfoGetRequest req1 = new TradeFullinfoGetRequest();
req1.setFields( "tid");
req1.setTid(6666666666661L); //訂單1
TradeFullinfoGetRequest req2 = "tid");
req2.setTid(66666666666622
TaobaoBatchRequest req = new TaobaoBatchRequest();
req.addRequest(req1);
TaobaoBatchResponse rsp = client.execute(req, 的sessionkey
5.2、詢問多個商家多個訂單詳情
BatchTaobaoClient client = new BatchTaobaoClient ( ?","test","test");
#
req1.setFields( ”tid");
商家a的訂單1
TradeFullinfoGetRequest re req2.setFields( req2.setFields( "tid");
# req
TradeFullinfoGetRequest req3 = q3.setFields( "tid");
req3.setTid(8888888888881L) req3.setTid(8888888888881L) req3.setBatchApiSession( "testtest "); //商家b的sessionkey
aoBatchRequest();
req.addRequest(req1);
##req.addRequest(req2);
req.addRequest(req3);
# TaobaoBatchResponse rsp = client.execute(req, "測試"); //商家的sessionkey
#
req1.setFields( ”tid");
商家a的訂單1
TradeFullinfoGetRequest re req2.setFields( req2.setFields( "tid");
# req
TradeFullinfoGetRequest req3 = q3.setFields( "tid");
req3.setTid(8888888888881L) req3.setTid(8888888888881L) req3.setBatchApiSession( "testtest "); //商家b的sessionkey
aoBatchRequest();
req.addRequest(req1);
##req.addRequest(req2);
req.addRequest(req3);
# TaobaoBatchResponse rsp = client.execute(req, "測試"); //商家的sessionkey
5.3、詢問多個商家訂單和商品詳情
BatchTaobaoClient client = new BatchTaobaoClient ( ?","test","test");
#
req1.setFields( ”tid");
商家a的訂單1
TradeFullinfoGetRequest re req2.setFields( req2.setFields( "tid");
# req
ItemSellerGetRequest req3 = .setFields( "num_iid");
req3.setNumIid(8888888881L) req3.setBatchApiSession( "testtest "); //商家b的sessionkey
aoBatchRequest();
req.addRequest(req1);
##req.addRequest(req2);
req.addRequest(req3);
# TaobaoBatchResponse rsp = client.execute(req, "測試"); //商家的sessionkey
#
req1.setFields( ”tid");
商家a的訂單1
TradeFullinfoGetRequest re req2.setFields( req2.setFields( "tid");
# req
ItemSellerGetRequest req3 = .setFields( "num_iid");
req3.setNumIid(8888888881L) req3.setBatchApiSession( "testtest "); //商家b的sessionkey
aoBatchRequest();
req.addRequest(req1);
##req.addRequest(req2);
req.addRequest(req3);
# TaobaoBatchResponse rsp = client.execute(req, "測試"); //商家的sessionkey
FAQ
测试环境下与正式环境下的API调用量有限制吗?