Score:0

How can I send a multipart/post-data POST request via a resource controller?

um flag

By trying to create a custom REST API through a resource controller via a custom module in Drupal 9, I would like to be able to send my data from a multipart/form-data Content-Type in order to pass files along with my textual data.

To be more precise, I have a Drupal content type with different text fields and with the possibility for the user to add attachments.

Currently I can only use a JSON format (via raw from Postman) for textual data which is not practical for sending files from my API making it impossible because the Content-Type application/json does not allow it.

As soon as I switch to multipart/form-data from Postman, my api gives me the following error: "No route found that matches "Content-Type: multipart/form-data; boundary=[...]"

Here is a snippet of my code:

class FormuelResource extends ResourceBase {

  /**
   * Requete POST pour la création d'un formuel
   * 
   * @param array $data
   *
   * @return \Drupal\rest\ResourceResponse
   *
   * @throws \Symfony\Component\HttpKernel\Exception\HttpException
   */
  public function post(array $data) {

    $msgRecap = ['message' => 'Vous venez de créer le formuel suivant : '.$data["title"]. '. Un email de confirmation vient de vous être envoyé.'];
  
    $typeContenu  = 'formuel';
    $node = Node::create(['type' => $typeContenu]);
    $node->uid = 1;
    $node->promote = 0;
    $node->sticky = 0;

    // Champs du formuel

    // Identification de l'agent
    $email = $data["identifiant"].'@mail.com';

    $node->field_uuid = $data["uid"];
    $node->field_identifiant = $data["identifiant"];
    $node->field_email = $email;
    $node->field_prenom = $data["prenom"];
    $node->field_nom= $data["nom"]; 
    $node->field_num_tel = $data["tel"];
    $node->field_site = $data["site"];
    $node->field_pieces_jointes = $data["pj"]; // files
    $node->field_api = true;

    $node->field_app_ou_materiel = $data["app"];
    $node->title=  $data["title"];
    $node->body = $data["body"];
        
    $node->save(); // Sauvegarde dans la base du formuel
    $nid = $node->id(); // Récupération nid

    [...]

    $response = new ResourceResponse($msgRecap);

    $response->addCacheableDependency($msgRecap);
    return $response;

   }

}

Which gives me at the level of my request in JSON on Postman:

URL : http://localhost/api/formuel/add?_format=json

raw :

{
    "uid": "123456",
    "identifiant": "john.doe",
    "prenom": "John",
    "nom": "DOE",
    "tel": "0623456789",
    "site": "My site",
    "app": 4,
    "title": "Test title node via API",
    "body": "Content node via API"
}

Response (success) :

{
    "message": "Vous venez de créer le formuel suivant : Test Formuel API 115. Un email de confirmation vient de vous être envoyé."
}

But going through the form-data with all of my keys and inserting files gives me an error :

Postman API error

Thank you in advance for your reply :)

Jaypan avatar
de flag
Not the answer you are looking for, but you can encode files in base64 to send them as strings. That's how I've dealt with posting images to a REST endpoint in the past.
Quentin avatar
um flag
@Jaypan Yes, base64 encoding is still a solution but unfortunately only for images :/ In my API I want to make sure that users can also send files like txt, csv, odp, docx, zip...
Jaypan avatar
de flag
I don't believe there is any limitation on the type of file that can be encoded to Base64, though your server may need helpers for that. But I see some results for encoding csv and pdf in base64 when I google it.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.