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
Change you store route like this:
Route::post('article/store', 'ArticleController@store');
Because you send post request from Postman to
/article/store
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With