Laravel MethodNotAllowedHttpException Explained

September 27th, 2024 • 3 minutes read time

If you see a MethodNotAllowedHttpException when accessing routes or submitting forms in Laravel, here's why that happens and how to fix it.

When we define routes in Laravel, we use the Route facade to specify which HTTP method it should respond to. Here's an example:

Route::get('/users', UserController::class)->name('users');

This route would be accessible as GET request (you visit it in the browser).

Here's an addition to this, where we're also able to POST through to a /users endpoint to store a user:

Route::get('/users', UserController::class)->name('users');
Route::post('/users', UserStoreController::class)->name('users.store');

Because both of these routes share the same path (/users), we're able to either visit it in the browser or POST through with a form, like this:

<form action="{{ route('users.store') }}" method="post">
    @csrf

    <!-- Your form fields here -->

     <button type="submit">Create user</button>
</form>

A MethodNotAllowedHttpException exception is thrown in Laravel when you attempt to send an HTTP request to a route, and the method hasn't explicitly been defined.

Here's an example:

Route::post('/topics', TopicStoreController::class)->name('topics.store');

Imagine this is the only route with the /topics path. By attempting to visit /topics in your browser, a MethodNotAllowedHttpException will be thrown because no GET route exists for this.

The opposite is true for any HTTP method.

Accidently using GET instead of POST

A common reason for the MethodNotAllowedHttpException exception being thrown is that you've defined a route where you mean to create a resource but use the GET HTTP method.

Here's an example:

Route::get('/users', UserStoreController::class)->name('users.store');

This route is intended to create a user, but by using the GET method, it won't match a POST request from a form. Therefore, you'll see a MethodNotAllowedHttpException!

Another common reason for seeing the MethodNotAllowedHttpException error is not using the correct method type when building forms.

Let's take our /users example route with the correct method:

Route::post('/users', UserStoreController::class)->name('users.store');

Suppose we were to build a form like this (without explicitly setting the method attribute on the form). In that case, we'd see a MethodNotAllowedHttpException error:

<form action="{{ route('users.store') }}">
    @csrf

    <!-- Your form fields here -->

     <button type="submit">Create user</button>
</form>

Another reason you may see the MethodNotAllowedHttpException error in Laravel is when working with PUT/PATCH/DELETE requests.

Let's say we have a route that deletes a user:

Route::delete('/users', UserDestroyController::class)->name('users.destroy');

Applying this to a form might look like this:

<form action="{{ route('users.destroy', $user) }}" method="post">
    @csrf
     <button type="submit">Delete this user</button>
</form>

This would result in a MethodNotAllowedHttpException exception because we're using POST, and the route is defined under DELETE.

No worries, though, you can spoof the HTTP method in Laravel, like this:

<form action="{{ route('users.destroy', $user) }}" method="post">
    @csrf
    @method('DELETE')
     <button type="submit">Delete this user</button>
</form>

Laravel will now know which method you're using and will find the correct route to send the request to.

Method spoofing is necessary because only GET and POST are supported in HTML forms. If you were building an API this wouldn't be a problem, but spoofing allows us to maintain a sensible set of HTTP methods for our resources.

When you're defining routes in Laravel, checking the few points we've covered in this article will help you avoid a MethodNotAllowedHttpException exception being thrown.

It's a little more work than using POST everywhere, but by making use of all of the HTTP methods available, you'll end up with a much cleaner set of routes!

If you found this article helpful, you'll love our practical screencasts.
Author
Alex Garrett-Smith
Share :

Comments

No comments, yet. Be the first!