Using the HTTP Client Connector with Multipart/Form-Data

Document created by thanh_n88 Employee on Jul 4, 2018Last modified by thanh_n88 Employee on Aug 13, 2018
Version 3Show Document
  • View in full screen mode

The HTTP client connector can be configured to send multipart/form-data. How the actual data looks will depend on what the endpoint is asking for. We'll focus on specifically form data, but other multipart variants should follow similar rules. Multipart/form-data is typically used for uploading/sending files. 

Related Information

 

Configuring the HTTP Connector

How the HTTP connection is set up does not affect how multipart/form-data request is formed. The endpoint you are sending the request to does affect how the body should look. The operation should have the Content Type field set to:

multipart/form-data; boundary=testboundary

 

The boundary name is arbitrary and can be anything but I recommend keeping it simple, it is used to define the different parts you are sending in your request. The HTTP Method and options below should match what the endpoint is asking for and your needs. Leave your request/response profiles as none since the request is not XML/JSON (if the response is, choose accordingly). 

 

Configuring the Request Body

Below is an example of a generic request body:

--testboundary
Content-Disposition: form-data; name="var1"

 

some_key
--testboundary

Content-Disposition: form-data; name="var2"

 

another_key
--testboundary
Content-Disposition: form-data; name="file"; filename="my-file.txt"

Content-Type: text/plain

 

test words etc OR use {1} and set {1} as your current data in the message shape
--testboundary--

 

Some common rules:

  1. Boundary: the boundary of your parts are determined by what you named your boundary in the content type field, in this case "testboundary", so now each part of your data needs to be surrounded by the boundary in the format of --<<boundary_name>>, e.g. --testboundary. The whole request must end with --<<boundary_name>>--, e.g. 
    --testboundary--
    Note: 
    your content type could be some variant of multipart, e.g. multipart/mixed; boundary=someboundary, but how the boundary works is still the same
  2. Content-Type: the Content-Type header within the boundary header determines what type of data that part of the request is, it can be any of the HTTP allowed values, should match your actual data type/file you are sending. You do not need to set an additional Content-Type header for normal form data parts
  3. Content-Disposition: "Content-Disposition: form-data" is used for form data to construct a form field name and key pair e.g. you are sending a form field named "var1" and it has a key of "some_value"; a form field named "var2" with a key of "another_key". What the form field name and key pair should be is determined by the endpoint.
  4. For sending a file, it is similar (or the same) to the syntax above, you're sending a form field named "file", the file's name is "my-file.txt", and the key (or contents) of my-file.txt is set after it. Alternatively, you can set it as a variable in the message using the usual {1}, {2}, etc and setting those variables as current data or some dynamic process property, etc
  5. Line Ending: it is expected that lines end with CRLF i.e. \r\n in multipart requests so after your message shape, add a data process shape to do a search for [\n] and replace with [\r][\n]
  6. Additional Headers: if needed, you can set additional headers in that block of headers, before or after the Content-Type. For example, you're sending binary data (Content-Type: application/octet-stream), you will need to encode the data in base 64 first, set it as {1} current data and then add a Content-Transfer-Encoding header in the request body:
    --testboundary
    Content-Disposition: form-data; name="content"; filename="Test.zip"
    Content-Transfer-Encoding: base64
    Content-Type: application/octet-stream

    {1}
    --testboundary--

 

Note: We are using Content-Disposition: form-data in the examples because the multipart is of a form-data type, if you are using something else with multipart, change the content-disposition accordingly, or it might not be needed at all

 

Examples of Request Bodies

Uploading a file to Box

According to Box's cURL example (-F is for form data):

-F attributes='{"name":"tigers.jpeg", "parent":{"id":"11446498"}}'
-F file=@myfile.jpg

An example of a request body for Box's upload API:

--testboundary
Content-Disposition: form-data; name="attributes"

 

'{"name":"my-file.txt","parent":{"id":"0"}}'
--testboundary
Content-Disposition: form-data; name="file"; filename="my-file.csv"

Content-Type: text/plain

 

{1}
--testboundary--

 

We're supposed to send a form field named attributes with the key of {"name":"tigers.jpeg", "parent":{"id":"11446498"}}. There is a pair of single quotes around the key in the message shape because of how JSON data works in the message shape, JSON data needs to be wrapped in single quotes, otherwise no single quotes needed. 

 

Then there's a form field named file with the key of the file contents (for cURL, the file path). In the HTTP request body, that will be followed by file name and actual contents. In this case {1} is current data for the actual contents of the .csv file and has a file name of my-file.csv.

 

Sending an image

Here's an example of sending an image file:

--testboundary

Content-Disposition: form-data; name="artifact"; filename="some-picture.jpg"; 

Content-Type: image/jpeg

 

...(binary bytes of the image)...

--testboundary--

Same things as before, except content type is image/jpeg and the contents are the binary bytes of the image. Depending on the endpoint, what the expected data is can be different (it could be base64 encoded, binary, etc), so adjust data and headers accordingly. There's a form field named artifact with a key of the image contents and file name of some-picture.jpg.

 

Using Einstein's Prediction API

Here's is SFDC's cURL example:

-F "sampleId=Photo Prediction"

-F "sampleLocation=http://www.mysite.com/our_beach_vacation.jpg"

-F "modelId="

An example of a request body for Einstein:

--testboundary
Content-Disposition: form-data; name="sampleId"

 

Photo Prediction
--testboundary
Content-Disposition: form-data; name="modeIId"

 

YCQ4ZACEPJFGXZNRA6ERF3GL5E

--testboundary
Content-Disposition: form-data; name="sampleLocation"

 

http://www.mysite.com/our_beach_vacation.jpg
--testboundary--

There's a form field named sampleId with the key of Photo Predictionfield named modelId with the key of YCQ4ZACEPJFGXZNRA6ERF3GL5Efield named sampleLocation with the key of http://www.mysite.com/our_beach_vacation.jpg.

 

Example of process

An example of a simple process with just a request body:

 

and the data process shape: 

 

 

Of course you can have other shapes and messages shapes to form the variables that go into the request body before the final composition that is sent to the HTTP connector.

 

Special Thanks

To Kyle Wetzler for helping with the testing

1 person found this helpful

Attachments

    Outcomes