HungryBus's avatar

PUT method returns 405

Hello :)

A very strange bug appears on production. When calling the Laravel 12 API via PUT, the return is 405 Not Allowed, however changing the same method to POST works fine for some reason.

Locally, it works both with PUT/POST.

This is the routes file:

Route::prefix('payers')
            ->name('payers.')
            ->controller(PayerController::class)
            ->group(function () {
                Route::get('/', 'index')
                    ->middleware('abilities:view-payers')
                    ->name('index');

                // This is the problem: changing it to POST works fine
                Route::put('/', 'store')
                    ->middleware('abilities:create-payer')
                    ->name('store');

                Route::patch('{payer}', 'update')
                    ->middleware('abilities:update-payer')
                    ->name('update');

                Route::delete('{payer}', 'destroy')
                    ->middleware('abilities:delete-payer')
                    ->name('destroy');
            });

I have to note, that there is no any conflict between my "caller" app and "callable" app: when I toggle between POST/PUT, I do it in both places.

I also have to note that production "callable" app is being hosted on the Debian server with Plesk installed, served via Nginx. At first, I thought that there might be some directives I should to include to allow additional request verbs, like PUT/PATCH/DELETE, but no - it works fine for other apps on the same server.

0 likes
6 replies
DigitalArtisan's avatar

PUT updates all data, PATCH allows partial update, and POST creates data.

So, your store route should be a POST in my opinion. And PATCH/PUT should be update route.

HungryBus's avatar

Yeah, might be, however... both PUT & PATCH & DELETE methods not working with The HTTP verb used to access this page is not allowed. 405 HTTP error code.

DigitalArtisan's avatar

Exactly, not working. You have these routes:

  GET|HEAD        payers .............. payers.index › PayerController@index
  PUT             payers .............. payers.store › PayerController@store
  PATCH           payers/{payer} ...... payers.update › PayerController@update
  DELETE          payers/{payer} ...... payers.destroy › PayerController@destroy

I would think you need this:

  GET|HEAD      payers .............. payers.index › PayerController@index
  POST          payers .............. payers.store › PayerController@store
  PUT|PATCH     payers/{payer} ...... payers.update › PayerController@update
  DELETE        payers/{payer} ...... payers.destroy › PayerController@destroy

Your error message is correct for your routing.

DigitalArtisan's avatar

You are probably missing the following in your view:

<form method="POST" action="/payers/{{ $payer->id }}">
    @csrf
    @method('PUT')   {{-- or PATCH / DELETE --}}
</form>
Snapey's avatar

check also what happens at the end of the function, because sometimes the post/patch works fine but its the redirect that fails.

1 like
HungryBus's avatar

There's no redirect there: response()->json([PayerResource::collection($payers)]);.

Please or to participate in this conversation.