POST /api/3.16/sites/14d41e12-74ea-4b7d-83bd-ed254673e929/datasources?datasourceType=tdsx HTTP/1.1
Content-Type: multipart/mixed; boundary=--------------------------808837830458042221641451
X-Tableau-Auth: 1lSU84EiSBKAXGt_hPU5Gg|VJS7K3mbSJcRro0BSGXoPBBsYu5IBC6k|14d41e12-74ea-4b7d-83bd-ed254673e929
User-Agent: PostmanRuntime/7.29.2
Accept: */*
Cache-Control: no-cache
Postman-Token: a05306e4-79d0-43de-96f1-8d50b5426a21
Host: 10ay.online.tableau.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: AWSELB=A1C7138F06714863BC67FB7B4BBB58E53F877896C9BF741843C826233D1F67A88AB8B733971A833BFCC5EF7A67795ABA4A5EC3D87B74C8D6293A5A1263BB5EFE685E5ECE1C4DFAAE9CBCF370BFCEBB3C0290447EB5; hid=10aypd-hap02
Content-Length: 1601179
----------------------------808837830458042221641451
Content-Disposition: form-data; name="request_payload"
Content-Type: text/xml
<tsRequest>
<datasource name="SuperStore"
useRemoteQueryAgent="False"
description="SuperStore Sales Data Source">
<project id="4972f17f-a8f8-4a92-a3ec-8f89371cda49" />
</datasource>
</tsRequest>
----------------------------808837830458042221641451
Content-Disposition: form-data; name="tableau_datasource"; filename="Sample - Superstore.tdsx"
Content-Type: application/octet-stream
<Sample - Superstore.tdsx>
----------------------------808837830458042221641451--
Our servers respond to the above request with:
<error code="400000">
<summary>Bad Request</summary>
<detail>Payload is either malformed or incomplete</detail>
</error>
Our endpoint requires that the Request Body look like this:
--boundary-string
Content-Disposition: name="request_payload"
Content-Type: text/xml
<tsRequest>
<datasource name="Sales"
useRemoteQueryAgent="False"
description="Sales Data Source">
<connectionCredentials name="janedoe"
password="xxxxxx"
embed="True" />
<project id="ff2a8360-3c2b-4b05-a793-7607c602e1fb" />
</datasource>
</tsRequest>
--boundary-string
Content-Disposition: name="tableau_datasource"; filename="Sales.TDSX"
Content-Type: application/octet-stream
content-of-datasource-file
--boundary-string--
Describe the solution you'd like
We would like the same level of support for multipart/mixed as is currently offered for multipart/form-data headers. We also have methods that use multipart/form-data and users are able to successfully send requests with Postman.
Currently, multipart/form-data headers are created by the Postman UI automatically and result in this:
Content-Type: multipart/form-data; boundary=<calculated when request is sent>
Which will result in a header that looks like this when sent:
Content-Type: multipart/form-data; boundary=--------------------------808837830458042221641451
It is not necessary to significantly alter the current Postman UI, perhaps provide a dropdown so users can choose between mixed and form-data content types under the form-data selector. This will effectively create valid boundary strings automatically for the end user.
Additionally when selecting multipart/mixed, the Content-Disposition must be set to the correct value (Content-Disposition: mixed;?) rather than Content-Disposition: form-data;.
Describe alternatives you've considered
Manually writing the header value. This creates valid Content-Type and boundary strings but will still add form-data as the Content-Disposition.
I have also tried sending requests using a multipart/form-data header generated automatically by the UI and I get the following error response from our servers:
<error code="406000">
<summary>Bad Request</summary>
<detail>Content type 'multipart/form-data;boundary=--------------------------615924037189507167035811' not supported</detail>
</error>
Users can send successful requests via cURL however, it is possible that lack of first-class support for multipart/mixed will make it difficult or impossible to adequately describe the method in a collection and generate valid code without requiring users to understand how to configure a cURL request to make it work.
There are other similar GH issues that are either open or have been closed as duplicates:
#8203
#6933
#1104
#6140
Additional context
In other words, a key workflow/scenario on our platform is currently blocked since our aim is to enable internal and external stakeholders to send requests and generate valid code without needing to have enough expertise to do so from our API documentation alone.
This is stopping us from making a public release of the collection to Salesforce's Public Workspace.
The following cURL request generated by Postman works:
curl --location --request POST 'https://10ay.online.tableau.com/api/3.16/sites/{{your-site-id}}/datasources?datasourceType=tdsx' \
--header 'Content-Type: multipart/mixed; boundary=--------------------------808837830458042221641451' \
--header 'X-Tableau-Auth: {{valid-api-key}}' \
--header 'Cookie: AWSELB=A1C7138F06714863BC67FB7B4BBB58E53F877896C9BF741843C826233D1F67A88AB8B733971A833BFCC5EF7A67795ABA4A5EC3D87B74C8D6293A5A1263BB5EFE685E5ECE1C4DFAAE9CBCF370BFCEBB3C0290447EB5; hid=10aypd-hap02' \
--form 'request_payload="<tsRequest>
<datasource name=\"SuperStore\"
useRemoteQueryAgent=\"False\"
description=\"SuperStore Sales Data Source\">
<project id=\"4972f17f-a8f8-4a92-a3ec-8f89371cda49\" />
</datasource>
</tsRequest>";type=text/xml' \
--form 'tableau_datasource=@"Sample - Superstore.tdsx"'
W3 defines multipart/mixed as:
7.2.2 The Multipart/mixed (primary) subtype
The primary subtype for multipart, "mixed", is intended for use when the body parts are independent and intended to be displayed serially. Any multipart subtypes that an implementation does not recognize should be treated as being of subtype "mixed".
Microsoft describes it as:
multipart/mixed [RFC1521]: The multipart/mixed content type is used when the body parts are independent and need to be bundled in a particular order. When a UA does not recognize a multipart subtype, it will treat the message as multipart/mixed.
If you look at RFC1521 it indicates that "mixed" is the primary subtype of the multipart content type and a pretty big gap for Postman in that case. On the other hand multipart/form-data is defined under RFC1867 for "Form-based File Upload in HTML".