I'm working on a Laravel 10.x project with an API that allows updating an event using a PUT /events/{id} endpoint. This endpoint accepts multipart/form-data to optionally upload an image and pdf, and also includes standard fields like title, description, event_date, location, etc.
Here’s the relevant Swagger/OpenAPI documentation for the request body:
#[OA\RequestBody(
request: "EventUpdateRequest",
required: true,
content: [
new OA\MediaType(
mediaType: "multipart/form-data",
schema: new OA\Schema(
type: "object",
properties: [
new OA\Property(property: "_method", type: "string", default: "PUT"),
new OA\Property(property: "title", type: "string", example: "Updated Event"),
new OA\Property(property: "sort_order", type: "integer", example: 1),
new OA\Property(property: "image", type: "string", format: "binary"),
new OA\Property(property: "pdf", type: "string", format: "binary")
// ... other fields
]
)
)
]
)]
The controller method:
/**
* @OA\Post(
* path="/events/{id}",
* tags={"Events"},
* summary="Etkinlik güncelle",
* description="Belirtilen ID'ye sahip etkinliği günceller. Eğer dosya (image, pdf) içeren multipart/form-data kullanılıyorsa, `_method=PUT` alanı eklenmelidir.",
* security={{"sanctum": {}}},
* @OA\Parameter(name="id", in="path", required=true, description="Etkinlik ID'si", @OA\Schema(type="integer")),
* @OA\RequestBody(ref="#/components/requestBodies/EventUpdateRequest"),
* @OA\Response(response=200, ref="#/components/responses/StandardSuccess"),
* @OA\Response(response=422, ref="#/components/responses/ValidationError"),
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
* @OA\Response(response=500, ref="#/components/responses/ServerError")
* )
*/
public function update(UpdateEventRequest $request, int $id)
{
try {
$dto = UpdateEventDTO::fromRequest($request);
$image = $request->hasFile('image') ? $request->file('image') : null;
$pdf = $request->hasFile('pdf') ? $request->file('pdf') : null;
$event = $this->eventService->updateEvent($id, $dto, $image, $pdf);
return ApiResponse::success(
new EventResource($event),
'Etkinlik başarıyla güncellendi'
);
} catch (InvalidArgumentException $e) {
return ApiResponse::error('Etkinlik bulunamadı', 404);
} catch (Exception $e) {
return ApiResponse::error('Etkinlik güncellenirken bir hata oluştu', 500);
}
}
The Route:
Route::middleware('role:super_admin,editor')->group(function () {
Route::get('/events/filters/upcoming', [EventController::class, 'upcoming']);
Route::get('/events/filters/past', [EventController::class, 'past']);
Route::get('/events/search', [EventController::class, 'search']);
Route::get('/events/statistics', [EventController::class, 'statistics']);
Route::get('/events/grouped-by-month', [EventController::class, 'groupedByMonth']);
Route::put('/events/{id}/sort-order', [EventController::class, 'updateSortOrder']);
Route::apiResource('events', EventController::class);
});
In my Laravel 10 API project, I have a PUT
/events/{id}
endpoint that should accept multipart/form-data to upload files (e.g. image, pdf) along with regular fields like title and sort_order. I’m using Swagger UI to test this.
When I send a real PUT request with multipart/form-data, Laravel receives an empty request ($request->all() is empty). However, if I send the same request as POST and include _method=PUT in the form data, it works as expected.
The Swagger request body is correctly defined with multipart/form-data and file inputs. I would like to use the actual PUT method, not method spoofing. Is this a limitation in Laravel regarding multipart/form-data with PUT requests, or is there a reliable way to make this work as intended?
Use method spoofing. This is the most reliable and Laravel-supported way to handle file uploads when updating resources.
Instead of sending a real PUT request, keep your HTTP method as POST and include a form-data field named _method
with the value PUT
. This allows PHP to correctly parse the multipart/form-data request, and Laravel will internally treat it as a PUT request.
In Swagger or OpenAPI documentation, define the request method as POST and include _method
in the form data with a default value of PUT. This ensures compatibility with Laravel and allows both file uploads and form fields to be handled properly.