OpenAPI

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

The response of the above batch request is shown in the below snippet. It containsresponses for all the request sent in batch response body in the same order as of the requests sent in the batch. As can be seen in the below snippet, the first response correspond to the request for endpoint " /sim/openapi/ref/v1/currencies" whereas the second response correspond to the request for the endpoint "/sim/openapi/ref/v1/timezones" which is exactly the same order in which the requests are sent in the batch. 
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).