Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"405 Method not allowed" in Laravel 5.6.14

I am just learning laravel resource methods to build a basic API. Below is the code of my api.php file that shows all the API routes.

// List Articles
Route::get('articles', 'ArticleController@index');

// List Single Article
Route::get('article/{id}', 'ArticleController@show');

// Create New Article
Route::post('article', 'ArticleController@store');

// Update Article
Route::put('article', 'ArticleController@store');

// Delete Article
Route::delete('article/{id}', 'ArticleController@destroy');

This works perfectly on get and delete methods. But for Post method, it is throwing error "405 Method not allowed". I am using Postman to test the API calls.

To be specific, below is the exact error Postman shows

Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException

Also attaching screenshot of Postman enter image description here

like image 667
aslamdoctor Avatar asked Mar 30 '18 06:03

aslamdoctor


2 Answers

Change you store route like this:

Route::post('article/store', 'ArticleController@store');

Because you send post request from Postman to

/article/store

enter image description here

like image 111
Kostiantyn Shtukert Avatar answered Oct 06 '22 01:10

Kostiantyn Shtukert


A MethodNotAllowedHttpException indicates the POST route can not be found for the requested url, but other methods are available.

This can be because you did not define it (correctly), or it has a conflict with another route in your config.

You can check the current routes with php artisan route:list

If you want to use resource controllers, instead of defining all the resource routes and actions yourself, why are you not using the Route::resource() method?

Route::resource('article', ArticleController::class);

This will generate all resource routes for you:

Verb        Path                    Action  Route Name
GET         /article                index   article.index
GET         /article/create         create  article.create
POST        /article                store   article.store
GET         /article/{article}      show    article.show
GET         /article/{article}/edit edit    article.edit
PUT/PATCH   /article/{article}      update  article.update
DELETE      /article/{article}      destroy article.destroy

The action translates to the action name in your controller, so for example, a request to POST /article will call the controller action: ArticleController@store.

In your case, I see that you are not using create or edit views, so instead of using the Route::resource() method, you can use the Route::apiResource() method, which will exclude routes that present HTML views for creating and editing your articles.

Route::apiResource('article', Api\ArticleController::class);

This will create your routes like:

Verb        Path                    Action  Route Name
GET         /article                index   article.index
POST        /article                store   article.store
GET         /article/{article}      show    article.show
PUT/PATCH   /article/{article}      update  article.update
DELETE      /article/{article}      destroy article.destroy

You can also auto-generate the resource controller to match your resource routes, this will generate the controller file for you.

php artisan make:controller Api/ArticleController --api

This will generate that file in Http/Controllers/Api/ArticleController with a mock of all the actions defined by the route which you can then use.

More info on resource controllers

PS.

Your PUT route does not take an id and it calls store, it is good practice to split the actions for POST (creating new) and PUT/PATCH (full/partial update of existing objects) in your controller.

Reason for this is that by convention, POST will create a new entity and doing a post again will (most likely) create another, so every request will have a different result.

PUT requests, on the other hand, are idempotent, meaning you should be able to do a PUT request multiple times on the same object and the output should be the same for all these requests. PATCH is a bit of a weird one here, it can be idempotent, but is not required. But when using Laravel, PATCH requests are usually handled by the same controller action which handles the PUT requests, and (depending on implementation) will be idempotent.

PSS.

I would not recommend using POST /article/store and follow the REST convention of doing a POST on the resource name itself instead. POST /article

like image 39
Robert Avatar answered Oct 06 '22 01:10

Robert