平台技术-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 协议内容

请求URL:

http://gw.api.taobao.com/router/batch

POST:

http://gw.api.taobao.com/router/batch?sign=5336DB2C525E1A3AD1013BC82C4437B2&timestamp=2016-01-05+10%3A15%3A15&v=2.0&app_key=4272&sign_method=hmac&format=json &session=6102b110f51625dcd2d1921ba80c6d2b43a2a5a37e7c7c73627811065
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"}}

Response:情况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,"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":" 测试发布收费课 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:响应报文只有一条结果;比如签名,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");} //注:使用该方式,需要下载最新的sdk,老的sdk暂未支持批量调用功能

4.2 创建BatchRequest

TaobaoBatchRequest batchRequest =       new TaobaoBatchRequest();

4.3 添加请求API

batchRequest.addRequest(timeGetRequest1)
                                     .addRequest(timeGetRequest2)
                                     .addRequest(timeGetRequest3)
                                     .addRequest(timeGetRequest4)
                                     .addRequest(fullinfosRequest1)
                                     .addRequest(fullinfosRequest2)
                                     .addRequest(fullinfosRequest3);

4.4 提交请求

TaobaoBatchResponse       response = client.execute(batchRequest);
 

4.5 遍历结果

if (response.isSuccess()) {
                   for (int i = 0; i < response.getResponseList().size(); i++) 
                         println("body:" + response.getResponseList().get(i).getBody());
             }

4.6 随机查询结果

if (response.isSuccess()) {
                          TimeGetResponse resp1  =  response.getResponse(timeGetRequest1);
                           if(timeGetResponse1.isSuccess())
                                       println(“服务器时间:" + resp1.getTime());
                           TradeFullinfoGetResponse rep2 =  response.getResponse(fullinfosRequest3);
}

注:使用sdk实现批量api调用功能 ,需要下载最新的sdk,sdk下载及使用点  这里

5、典型使用场景举例

以调用接口获取订单详情为例,原来要查询某个商家多个订单详情,需要重复发起多次请求;现如果使用批量方式调用,1次请求就可以返回多个结果,可以大大提高API调用效率。以下是常用使用场景sdk调用示例(java):

5.1、查询单个商家多个订单详情

BatchTaobaoClient client =       new BatchTaobaoClient (       "http://gw.api.taobao.com/router/batch?","test","test");         
           
     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、查询多个商家多个订单详情

BatchTaobaoClient client =       new BatchTaobaoClient (       "http://gw.api.taobao.com/router/batch?","test","test");         
             
     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、查询多个商家订单和商品详情

BatchTaobaoClient client =       new BatchTaobaoClient (       "http://gw.api.taobao.com/router/batch?","test","test");         
             
     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

测试环境下与正式环境下的API调用量有限制吗?