Introduction
Batching is an OpenAPI feature that allows you to pack several API requests and send them to the OpenAPI service in one HTTP request and receive a single HTTP response for all your requests in batch response body. This response can then be unpacked on the client side to get individual responses for the requests sent in batch. This way, you can optimize calls to the server. Request batching is a useful way of minimizing number of messages that are passed between client and server. This reduces network traffic and provides a smoother, less chatty user interface.
Which calls can be batched ?
Batching can be applied to resources that belong to the same service group. That is to say, it is not possible to group requests for multiple service groups in a single batch request. For example, a batch request containing Reference Data resources would be made towards "openapi/ref/batch", and similarly a batch request containing Portfolio resources would be made towards "openapi/port/batch".
OpenAPI services execute the batch request in a non-deterministic manner, so clients sending the batch should not assume that the order of execution within a batch request.
How to do it ?
Follow the steps given below for packaging multiple requests and un-packaging the responses:
Packaging multiple Requests
A sample batch request is shown in the below code snippet, batch request is a post on the batch endpoint with content-type header set as "multipart/mixed" and a boundary parameter. This indicates that the entity consists of several parts, each part itself with a structure that is syntactically identical to an RFC 822 message, except that the header area might be completely empty, and that the parts are each preceded by a unique string value or GUID which can be used as a boundary value (ex: --fe9898ef-b8f9-4a9f-bbd0-66ed3bf186b9). One also need to set Authorization header with access token as shown in the below snippet.
POST /sim/openapi/ref/batch HTTP/1.1 Content-Type: multipart/mixed; boundary="fe9898ef-b8f9-4a9f-bbd0-66ed3bf186b9" Authorization: Bearer eyJhbG.........
Batch request body of the sample batch request is shown below. Note how each request is separated by boundary value ("fe9898ef-b8f9-4a9f-bbd0-66ed3bf186b9") and "Host" header is set with same as parent request.
--fe9898ef-b8f9-4a9f-bbd0-66ed3bf186b9 Content-Type: application/http; msgtype=request GET /sim/openapi/ref/v1/currencies HTTP/1.1 Host: gateway.saxobank.com --fe9898ef-b8f9-4a9f-bbd0-66ed3bf186b9 Content-Type: application/http; msgtype=request GET /sim/openapi/ref/v1/timezones HTTP/1.1 Host: gateway.saxobank.com --fe9898ef-b8f9-4a9f-bbd0-66ed3bf186b9--
Un-packaging the Reponses
HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Type: multipart/mixed; boundary="6e19056d-dd22-4275-a5a1-56d21f064ace" Expires: -1 Access-Control-Allow-Origin: http://<yourhostname> Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: X-Auth-Token,X-Auth-Token-Expiry,X-Auth-Token-Expiry-Minutes,X-Request-Id,WWW-Authenticate,Location,Content-Encoding,ETag,Content-Range Date: Tue, 05 May 2015 08:51:48 GMT Content-Length: 10811 --6e19056d-dd22-4275-a5a1-56d21f064ace Content-Type: application/http; msgtype=response HTTP/1.1 200 OK Access-Control-Allow-Origin: http://<yourhostname> Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: X-Auth-Token,X-Auth-Token-Expiry,X-Auth-Token-Expiry-Minutes,X-Request-Id,WWW-Authenticate,Location,Content-Encoding,ETag,Content-Range Content-Type: application/json; charset=utf-8 {"Data":[{"CurrencyCode":"USD","Decimals":2,"Name":"US Dollar"},{"CurrencyCode":"GBP","Decimals":2,"Name":"British Pound"},{"CurrencyCode":"EUR","Decimals":2,"Name":"Euro"},{"CurrencyCode":"CHF","Decimals":2,"Name":"Swiss Franc"},{"CurrencyCode":"AUD","Decimals":2,"Name":"Australian Dollar"},{"CurrencyCode":"CAD","Decimals":2,"Name":"Canadian Dollar"},{"CurrencyCode":"NZD","Decimals":2,"Name":"New Zealand Dollar"},{"CurrencyCode":"JPY","Decimals":0,"Name":"Japanese Yen"},{"CurrencyCode":"DKK","Decimals":2,"Name":"Danish Krone"},{"CurrencyCode":"SEK","Decimals":2,"Name":"Swedish Krona"},{"CurrencyCode":"NOK","Decimals":2,"Name":"Norwegian Krone"},{"CurrencyCode":"ATS","Decimals":2,"Name":"Austrian Schilling"},{"CurrencyCode":"BEF","Decimals":2,"Name":"Belgian Franc"},{"CurrencyCode":"DEM","Decimals":2,"Name":"German Mark"},{"CurrencyCode":"ESP","Decimals":2,"Name":"Spanish Peseta"},{"CurrencyCode":"FIM","Decimals":2,"Name":"Finnish Mark"},{"CurrencyCode":"FRF","Decimals":2,"Name":"French Franc"},{"CurrencyCode":"GRD","Decimals":2,"Name":"Greek Drachma"},{"CurrencyCode":"IEP","Decimals":2,"Name":"Irish Punt"},{"CurrencyCode":"ITL","Decimals":2,"Name":"Italian Lira"},{"CurrencyCode":"LUF","Decimals":2,"Name":"Luxembourg Franc"},{"CurrencyCode":"NLG","Decimals":2,"Name":"Dutch Guilder"},{"CurrencyCode":"PTE","Decimals":2,"Name":"Portugese Escudo"},{"CurrencyCode":"CZK","Decimals":2,"Name":"Czech Koruna"},{"CurrencyCode":"ISK","Decimals":2,"Name":"Iceland Krona"},{"CurrencyCode":"PLN","Decimals":2,"Name":"Polish Zloty"},{"CurrencyCode":"SGD","Decimals":2,"Name":"Singapore Dollar"},{"CurrencyCode":"LTL","Decimals":2,"Name":"Lithuanian Litas"},{"CurrencyCode":"EEK","Decimals":2,"Name":"Estonian Kroon"},{"CurrencyCode":"HRK","Decimals":2,"Name":"Croatian Kuna"},{"CurrencyCode":"LVL","Decimals":2,"Name":"Latvian Lats"},{"CurrencyCode":"SIT","Decimals":2,"Name":"Slovenian Tolar"},{"CurrencyCode":"SKK","Decimals":2,"Name":"Slovak Koruna"},{"CurrencyCode":"AED","Decimals":2,"Name":"UAE Dirham"},{"CurrencyCode":"BHD","Decimals":2,"Name":"Bahrain Dinar"},{"CurrencyCode":"BRL","Decimals":2,"Name":"Brazilian Real"},{"CurrencyCode":"CNY","Decimals":2,"Name":"Chinese Yuan Renminbi"},{"CurrencyCode":"CNH","Decimals":2,"Name":"Offshore Chinese Renminbi"},{"CurrencyCode":"EGP","Decimals":2,"Name":"Egypt Pound"},{"CurrencyCode":"RUB","Decimals":2,"Name":"Russian Ruble"},{"CurrencyCode":"HKD","Decimals":2,"Name":"Hong Kong Dollar"},{"CurrencyCode":"HUF","Decimals":2,"Name":"Hungarian Forint"},{"CurrencyCode":"IDR","Decimals":2,"Name":"Indonesian Rupiah"},{"CurrencyCode":"ILS","Decimals":2,"Name":"Israeli Shekel"},{"CurrencyCode":"INR","Decimals":2,"Name":"Indian Rupee"},{"CurrencyCode":"JOD","Decimals":2,"Name":"Jordan Dinar"},{"CurrencyCode":"KRW","Decimals":2,"Name":"Korean Won"},{"CurrencyCode":"KWD","Decimals":2,"Name":"Kuwait Dinar"},{"CurrencyCode":"MAD","Decimals":2,"Name":"Moroccan Dirham"},{"CurrencyCode":"MXN","Decimals":2,"Name":"Mexican Peso"},{"CurrencyCode":"MYR","Decimals":2,"Name":"Malaysian Ringgit"},{"CurrencyCode":"OMR","Decimals":2,"Name":"Oman Sul Rial"},{"CurrencyCode":"PHP","Decimals":2,"Name":"Philipines Peso"},{"CurrencyCode":"QAR","Decimals":2,"Name":"Qatar Rial"},{"CurrencyCode":"SAR","Decimals":2,"Name":"Saudi Riyal"},{"CurrencyCode":"THB","Decimals":2,"Name":"Thai Baht"},{"CurrencyCode":"TRL","Decimals":2,"Name":"Turkish Lira"},{"CurrencyCode":"TRY","Decimals":2,"Name":"Turkish Lira"},{"CurrencyCode":"TWD","Decimals":2,"Name":"Taiwan Dollar"},{"CurrencyCode":"VEB","Decimals":2,"Name":"Venezuela Bolivar"},{"CurrencyCode":"ZAR","Decimals":2,"Name":"South African Rand"},{"CurrencyCode":"DZD","Decimals":2,"Name":"Algerian Dinar"},{"CurrencyCode":"IRR","Decimals":2,"Name":"Iranian Riyal"},{"CurrencyCode":"IQD","Decimals":2,"Name":"Iraqi Dinar"},{"CurrencyCode":"LBP","Decimals":2,"Name":"Lebanese Pound"},{"CurrencyCode":"LYD","Decimals":2,"Name":"Libya Dinar"},{"CurrencyCode":"SYP","Decimals":2,"Name":"Syrian Pound"},{"CurrencyCode":"TND","Decimals":2,"Name":"Tunisian Dinar"},{"CurrencyCode":"YER","Decimals":2,"Name":"Yemen Riyal"},{"CurrencyCode":"UAH","Decimals":2,"Name":"Ukraine Hryvnia"},{"CurrencyCode":"XPT","Decimals":2,"Name":"Platinum"},{"CurrencyCode":"XPD","Decimals":2,"Name":"Palladium"},{"CurrencyCode":"XAU","Decimals":2,"Name":"Gold"},{"CurrencyCode":"XAG","Decimals":2,"Name":"Silver"},{"CurrencyCode":"RON","Decimals":2,"Name":"Romanian leu"},{"CurrencyCode":"BGN","Decimals":2,"Name":"*Bulgarian Lev - to be disabled 20070205"},{"CurrencyCode":"ARS","Decimals":2,"Name":"Argentine Peso"},{"CurrencyCode":"CLP","Decimals":2,"Name":"Chilean Peso"},{"CurrencyCode":"GBX","Decimals":0,"Name":"British Pence"},{"CurrencyCode":"USX","Decimals":0,"Name":"US Cent"},{"CurrencyCode":"CYP","Decimals":2,"Name":"*Cypriot Pound - to be disabled 20080101"},{"CurrencyCode":"MTL","Decimals":2,"Name":"*Maltese Lira - to be disabled 20080101"},{"CurrencyCode":"XTI","Decimals":2,"Name":"CL Light Sweet Crude Oil (WTI)"},{"CurrencyCode":"ZAX","Decimals":0,"Name":"South African Cents"}]} --6e19056d-dd22-4275-a5a1-56d21f064ace Content-Type: application/http; msgtype=response HTTP/1.1 200 OK Access-Control-Allow-Origin: http://<yourhostname> Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: X-Auth-Token,X-Auth-Token-Expiry,X-Auth-Token-Expiry-Minutes,X-Request-Id,WWW-Authenticate,Location,Content-Encoding,ETag,Content-Range Content-Type: application/json; charset=utf-8 {"Data":[{"Abbreviation":"IDL","Name":"Dateline Standard Time","TimeZoneId":1},{"Abbreviation":"SST","Name":"Samoa Standard Time","TimeZoneId":2},{"Abbreviation":"HAST","Name":"Hawaiian Standard Time","TimeZoneId":3},{"Abbreviation":"AKST","Name":"Alaskan Standard Time","TimeZoneId":4},{"Abbreviation":"PST","Name":"Pacific Standard Time","TimeZoneId":5},{"Abbreviation":"MST","Name":"Mountain Standard Time","TimeZoneId":6},{"Abbreviation":"MST","Name":"Mountain Standard Time (Mexico)","TimeZoneId":7},{"Abbreviation":"MST","Name":"U.S. Mountain Standard Time","TimeZoneId":8},{"Abbreviation":"CST","Name":"Central Standard Time","TimeZoneId":9},{"Abbreviation":"CST","Name":"Canada Central Standard Time","TimeZoneId":10},{"Abbreviation":"CST","Name":"Central Standard Time (Mexico)","TimeZoneId":11},{"Abbreviation":"CST","Name":"Central America Standard Time","TimeZoneId":12},{"Abbreviation":"EST","Name":"Eastern Standard Time","TimeZoneId":13},{"Abbreviation":"EST","Name":"U.S. Eastern Standard Time","TimeZoneId":14},{"Name":"SA Pacific Standard Time","TimeZoneId":15},{"Abbreviation":"AST","Name":"Atlantic Standard Time","TimeZoneId":16},{"Name":"SA Western Standard Time","TimeZoneId":17},{"Name":"Pacific S.A. Standard Time","TimeZoneId":18},{"Abbreviation":"NST","Name":"Newfoundland Standard Time","TimeZoneId":19},{"Name":"E. South America Standard Time","TimeZoneId":20},{"Name":"SA Eastern Standard Time","TimeZoneId":21},{"Name":"Greenland Standard Time","TimeZoneId":22},{"Name":"Mid-Atlantic Standard Time","TimeZoneId":23},{"Abbreviation":"AZOT","Name":"Azores Standard Time","TimeZoneId":24},{"Name":"Cape Verde Standard Time","TimeZoneId":25},{"Abbreviation":"GMT","Name":"GMT Standard Time","TimeZoneId":26},{"Abbreviation":"GMT","Name":"Greenwich Standard Time","TimeZoneId":27},{"Abbreviation":"CET","Name":"Central Europe Standard Time","TimeZoneId":28},{"Abbreviation":"CET","Name":"Central European Standard Time","TimeZoneId":29},{"Abbreviation":"CET","Name":"Romance Standard Time","TimeZoneId":30},{"Abbreviation":"WET","Name":"W. Europe Standard Time","TimeZoneId":31},{"Abbreviation":"WAT","Name":"W. Central Africa Standard Time","TimeZoneId":32},{"Abbreviation":"EET","Name":"E. Europe Standard Time","TimeZoneId":33},{"Abbreviation":"EST","Name":"Egypt Standard Time","TimeZoneId":34},{"Name":"FLE Standard Time","TimeZoneId":35},{"Name":"GTB Standard Time","TimeZoneId":36},{"Abbreviation":"IST","Name":"Israel Standard Time","TimeZoneId":37},{"Abbreviation":"SAST","Name":"South Africa Standard Time","TimeZoneId":38},{"Name":"Russian Standard Time","TimeZoneId":39},{"Abbreviation":"AST","Name":"Arab Standard Time","TimeZoneId":40},{"Abbreviation":"EAT","Name":"E. Africa Standard Time","TimeZoneId":41},{"Abbreviation":"AST","Name":"Arabic Standard Time","TimeZoneId":42},{"Abbreviation":"IRST","Name":"Iran Standard Time","TimeZoneId":43},{"Abbreviation":"AST","Name":"Arabian Standard Time","TimeZoneId":44},{"Name":"Caucasus Standard Time","TimeZoneId":45},{"Name":"Ekaterinburg Standard Time","TimeZoneId":47},{"Name":"West Asia Standard Time","TimeZoneId":48},{"Abbreviation":"IST","Name":"India Standard Time","TimeZoneId":49},{"Abbreviation":"NPT","Name":"Nepal Standard Time","TimeZoneId":50},{"Abbreviation":"CST","Name":"Central Asia Standard Time","TimeZoneId":51},{"Name":"Sri Lanka Standard Time","TimeZoneId":52},{"Name":"N. Central Asia Standard Time","TimeZoneId":53},{"Abbreviation":"MMT","Name":"Myanmar Standard Time","TimeZoneId":54},{"Name":"SE Asia Standard Time","TimeZoneId":55},{"Name":"North Asia Standard Time","TimeZoneId":56},{"Abbreviation":"CST","Name":"China Standard Time","TimeZoneId":57},{"Abbreviation":"SGT","Name":"Singapore Standard Time","TimeZoneId":58},{"Name":"Taipei Standard Time","TimeZoneId":59},{"Abbreviation":"AWST","Name":"W. Australia Standard Time","TimeZoneId":60},{"Name":"North Asia East Standard Time","TimeZoneId":61},{"Abbreviation":"KST","Name":"Korea Standard Time","TimeZoneId":62},{"Abbreviation":"JST","Name":"Tokyo Standard Time","TimeZoneId":63},{"Abbreviation":"YAKT","Name":"Yakutsk Standard Time","TimeZoneId":64},{"Name":"AUS Central Standard Time","TimeZoneId":65},{"Abbreviation":"ACST","Name":"Cen. Australia Standard Time","TimeZoneId":66},{"Name":"AUS Eastern Standard Time","TimeZoneId":67},{"Abbreviation":"AEST","Name":"E. Australia Standard Time","TimeZoneId":68},{"Name":"Tasmania Standard Time","TimeZoneId":69},{"Abbreviation":"VLAT","Name":"Vladivostok Standard Time","TimeZoneId":70},{"Name":"West Pacific Standard Time","TimeZoneId":71},{"Abbreviation":"PST","Name":"Central Pacific Standard Time","TimeZoneId":72},{"Abbreviation":"FJT","Name":"Fiji Islands Standard Time","TimeZoneId":73},{"Abbreviation":"NZST","Name":"New Zealand Standard Time","TimeZoneId":74},{"Abbreviation":"TOT","Name":"Tonga Standard Time","TimeZoneId":75}]} --6e19056d-dd22-4275-a5a1-56d21f064ace--
PS: Request should be sent in exactly the same structure as shown above , Server will throw 500 internal server error if the structure is not correct.
There is a live sample of Batching requests (with source).