0

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?

0

2 Answers 2

0

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.

Sign up to request clarification or add additional context in comments.

Comments

0

Requests using FormData cannot be sent directly with PUT PATCH or DELETE  methods.

You need to use the POST method and "spoof" it by adding the _method field, setting it to PUT in your case.

For more information: PATCH and PUT Request Does not Working with form-data

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.