If you have a client application that captures certain information as multipart/form-data to be saved in Salesforce and requires some pre-processing before saving the information, then the first thing that comes to our mind is to quickly expose an API and build a custom REST Service in Salesforce like this
@RestResource(urlMapping='/Resource/v1')
global with sharing class MyApexService
{
@HttpPost
global static String doPost(){
// code to pre-process the incoming data before saving it
}
}
Unfortunately, if you try to call this API by submitting a multipart/form-data request, you will encounter an error as shown below and the reason is indeed what the error says i.e. Apex REST does not support multipart/form-data requests


JSON Comparison in APEX
Compare two JSONS with simple == operator just like comparing two variables. LHS and RHS JSON can have different values and order of keys; the comparator will consider only the overall schema/structure.
The Hack
Salesforce or any other server application identifies the incoming HTTP request type based on the Content-Type
header. Therefore the hack to make the custom API accept such requests is to remove that multipart/form-data from the header. This obviously isn't simple though! Why? To find that, we need to first understand how multipart/form-data request body looks like and how are they handled/processed by the server.

The Recipe - multipart/form-data
Jump to any API client like postman and create a multipart/form-data request by selecting the Body
as form-data

This allows you to send information as key-value pairs including file (read this article for multipart/form-data file upload to Salesforce with APEX REST Service). And if you explore the code snippet which is a sneak peak into how the form data is send in the HTTP body, you will see something like shown below in the snapshot. Here are the ingredients of the multipart/form-data recipe.
- The key is set in
name
attribute (e.g. Title highlighted below) followed by value (e.g. Inteygrate highlighted below) - Each key-value pair is separated by a random string called Boundary :
----WebKitFormBoundary7MA4YWxkTrZu0gW
. This is the most important spice and without this the server application cannot cook, i.e. process our request. - The server application uses this boundary value to identify from where does each key-value pair starts and ends. In the below snapshot you can see the boundary values at the beginning and at the end of each key-value pair. Boundary strings aren't fixed and are random; therefore in-order to let the server application know the boundary for a particular request - the same must be passed in the content-type header.
Actual value of Boundary might be different from what is shown in your API client.

This recipe of reading the boundary and processing each individual key-value pair is handled out-of-box by Salesforce for Standard REST APIs but for custom REST APIs we need to handle the logic. And this is why we say ...This obviously isn't simple though! in the hack section. So what is the solution? Simple, identify the boundary from the request body yourself and do not rely on the content-type header because we will be removing it 😬.

The Solution
For the request shown in the snapshot above the request body would look something like below: