PATCH and PUT Request Does not Working with form-data

notalentgeek picture notalentgeek · Jun 5, 2018 · Viewed 24.1k times · Source

I am using Laravel to create a RESTFUL application and I test the application with Postman. Currently, there is an issue for PATCH or PUT if the data sent from Postman with form-data.

// Parameter `{testimonial}` will be sent to backend.
Route::post  ('testimonials/{testimonial}', 'TestimonialController@update');

// Parameter `{testimonial}` will not be sent to backend (`$request->all()` will be empty) if sent from Postman with form-data.
Route::patch ('testimonials/{testimonial}', 'TestimonialController@update');
Route::put   ('testimonials/{testimonial}', 'TestimonialController@update');
  • Using form-data, $request->all() will be okay for POST.
  • Using x-www-form-urlencoded, $request->all() will be okay for PATCH, PUT, and POST.
  • However, if I am sending PUT and PATCH with form-data from Postman, the $request->all() will be empty (the parameters will not be sent to backend).

Right now the solution is to use POST for updating a model. I want to know why PATCH and PUT is not working when sent with form-data from Postman.

Answer

Script47 picture Script47 · Jun 5, 2018

This is a known issue and the workaround suggestion as per the following Github comment is that when sending a PATCH / PUT requests you should do the following:

You should send POST and set _method to PUT (same as sending forms) to make your files visible

So essentially you send a POST request with a parameter which sets the actual method and Laravel seems to understand that.

As per the documentation:

Since HTML forms can't make PUT, PATCH, or DELETE requests, you will need to add a hidden _method field to spoof these HTTP verbs. The @method Blade directive can create this field for you:

<form action="/foo/bar" method="POST">
    @method('PUT')

    ...
</form> 

Alternatively, you can use the method_field helper function to do the above:

The method_field function generates an HTML hidden input field containing the spoofed value of the form's HTTP verb. For example, using Blade syntax:

<form method="POST">
    {{ method_field('PUT') }}
</form>