"405 Method not allowed" in Laravel 5.6.14 - php

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 sll is active on your domain, you should request like HTTPS://yourdomain.com . You should check that, then try again.

The methodNotAllowed exception indicates that a route doesn't exist for the HTTP method you are requesting.
Your form is set up to make a POST request, so your route needs to use Route::post() to receive this.
Be sure that request on postman is set on POST
Remember to clear route cache after any route change:
php artisan route:cache
Try also changing settings on postman: Do not send anything in headers - I mean delete Content-Type

Related

Laravel routes same url but different name

I am new to Laravel and I am trying to make a function to create a database row but my routes are not working.
I currenlty have this in my web.php file:
Route::get('/admin/pagina', [PaginaOverzichtController::class, 'index'])
->name('Admin_Pagina_Overzicht')
->middleware('auth');
Route::post('/admin/pagina', [PaginaOverzichtController::class, 'CreatePage'])
->name('Admin_Pagina_CreatePage')
->middleware('auth');
Route::post('/admin/pagina', [PaginaOverzichtController::class, 'DeletePage'])
->name('Admin_Pagina_DeletePage')
->middleware('auth');
But when I go to /admin/pagina, I get a Route [Admin_Pagina_CreatePage] not defined error.
Am I allowed to have the same URL but different name pointing to a different function in the same controller? If not, is there a best-practice way to do this?
^
I have a form on my page that should create a page with the method post and action {{ route('Admin_Pagina_CreatePage') }}
Am I allowed to have the same url but differend name pointing to a differend function in the same controller?
No. When determining uniqueness in Laravel routes, the HTTP Method & URI act as a combined primary key. Everything else is just metadata attached to that unique entry.
In your example, the second Route::post('/admin/pagina') is overwriting the first one, because you've defined the same "ID" pair of POST /admin/pagina.
I'm not sure how you expect to have the same HTTP method and URI go to two separate controller actions. If you expect to route them differently based on what's included in the request body, that conflicts with how Laravel's routing works (routes are found and dispatched without usage of the request body).
Normally for a delete, you would utilize that HTTP method in the routing:
Route::delete('/admin/pagina' [/* ... */]);
This can be paired with form method spoofing to trick a normal form request (which doesn't support DELETE) to find that appropriate route anyway.
Not related to your problem it's just a suggestion, you can use Route Groups and assign a middleware to that group to avoid repetition of assigning one middleware to each route.
E.g.
Route::middleware(['auth'])->group(function(){
Route::get('/admin/pagina', [PaginaOverzichtController::class, 'index'])->name('Admin_Pagina_Overzicht');
Route::post('/admin/pagina', [PaginaOverzichtController::class, 'CreatePage'])->name('Admin_Pagina_CreatePage');
Route::post('/admin/pagina', [PaginaOverzichtController::class, 'DeletePage'])->name('Admin_Pagina_DeletePage');
});

Laravel automatize routes

I am using some routes in my laravel App like this:
Route::get('/structure', 'Superuser\StructureController#index');
So if I go to localhost/myproject/structure I am using StructureController and it's method "index".
Now I would like to use another features, like add, update, delete, reorder etc...
Is there any simple way, that I needn't to write:
Route::get('/structure/add', 'Superuser\StructureController#add');
Route::get('/structure/update/{url}', 'Superuser\StructureController#update');
Route::get('/structure/delete/{url}', 'Superuser\StructureController#delete');
If is this possible, I would like to use ::get for everything. Thank you a lot.
If you want to use GET for everything i dont think there is a built in automated way to do it, though you could write a method that spits out routes based on a passed in controller name perhaps.
There is automated RESTful/Resourceful routes for resource controllers:
Route::resource('photos', 'PhotoController');
This would generate these routes:
Actions Handled By Resource Controller
Verb URI Action Route Name
GET /photos index photos.index
GET /photos/create create photos.create
POST /photos store photos.store
GET /photos/{photo} show photos.show
GET /photos/{photo}/edit edit photos.edit
PUT/PATCH /photos/{photo} update photos.update
DELETE /photos/{photo} destroy photos.destroy
https://laravel.com/docs/5.5/controllers#resource-controllers

Error in Slim 3 because of mismatch in request uri & request method

I'm using Slim 3 Framework as my backend and a small self-written frontend (jQuery). In my frontend I have ajax commands to call my REST server.
Now I'm facing the problem that I can't use DELETE on my client because it is not matching the HTTP request method (GET).
405 Method not allowed. Must be one of: GET, PUT
The official documentation says said it is not allowed by default:
If your Slim Framework application has a route that matches the
current HTTP request URI but NOT the HTTP request method, the
application invokes its Not Allowed handler and returns a HTTP/1.1 405
Not Allowed response to the HTTP client.
Now I could use GET or PUT but that is not possibly because I already have those routes declared for other actions.
Slim Application Error:
The application could not run because of the following error:
Details
Type: FastRoute\BadRouteException
Message: Static route /api/v1/folders/ is shadowed by previously defined variable route /api/v1/folders/(.*) for method GET
// Folder routes
$this->group('/folders', function () {
$this->get('[/{params:.*}]', 'FolderController:index');
$this->post('', 'FolderController:create');
$this->put('[/{params:.*}]', 'FolderController:update');
$this->delete('/[/{params:.*}]', 'FolderController:delete');
})->add('AuthenticateMiddleware');
Could you please give me an advice on how to solve this? Isn't this a general problem in the REST-world so to speak, because I guess many frameworks act like Slim 3 and throw a 405 Method not allowed error in such particular situation where you want to use DELETE but can't because the click in the browser is GET?
As per my comment:
Is the failing request happening when you click on a link? <a></a> ? The request method has to be DELETE in order for Slim to invoke the right controller. Also note that your delete route has an extra [
Good luck !

Route::controller with optional parameters in Laravel 4

I'm just new to Laravel but I immediately fell in love with it. As a not so super experienced php developer I do find the official documentation, although very expansive, somewhat complicated to use and find everything I need.
My question is about the Routing component. As the documentation states you can assign a route to a controller with the Route::controller method. So if I want a Blog controller for all /blog/ routes I assign it like this:
Route::controller('blog', 'BlogController');
So then if I'd like to acces all my blog posts I acces the the getIndex method by www.foo.com/blog or www.foo.com/blog/index
But let's say I'd like to be able to display categories via a getCategory method. My url would look like www.foo.com/blog/category and if, for example, I want to get the news category from the DB by slug, I'd like to use: www.foo.com/blog/category/news as the URI.
My question now is, how do I pass the slug to the url and access it in the getCategory method? Do I need specify it via Route::get('blog/category/{slug}', 'BlogController#getCategory') or is there a way to use Route::controller('blog', 'BlogController') and to send and acces parameters from the URL in the getCategory method?
I already tried to find it via google and in the official documentation, but I couldn't find a crystal clear answer to this problem...
You can simply add parameters to your getCategory method:
public function getCategory($category) {
die($category);
}
If you initialize it to null in the parameter list, it becomes optional. Alternatively, you can always pull parameters from the Input object but they would need to be passed in querystring format:
$category = Input::get('category');
With that said, I'd caution against using the Controller route. It's handy and mimics traditional MVC frameworks, but I believe it's planned to be deprecated -- and honestly, you miss out on some pretty flexible features.
using Route::controller('blog', 'BlogController'); allows you to define a single route to handle every action in a controller using REST naming conventions.then you have to add methods to your controller, prefixed with the HTTP verb they respond to. That means if you have a method called getIndex() it will be executed when there is a GET request to the url "yoursite.com/blog".
To handle POST requests to the same url add a method prefixed with post(ex: postComment()) and so on for other http verbs PUT, PATCH and DELETE.
I think you want something more customized, so you can use a resource controller:
Route::resource('blog', 'BlogController');
This will generate some RESTful routes around the blog resource, run php artisan routes in your project folder to see the generated routes, it should be something like this:
Verb Path Action Route Name
GET /blog index blog.index
GET /blog/create create blog.create
POST /blog store blog.store
GET /blog/{blog} show blog.show
GET /blog/{blog}/edit edit blog.edit
PUT/PATCH /blog/{blog} update blog.update
DELETE /blog/{blog} destroy blog.destroy
in the action column are the functions that you should have in the controller.
If you want to define more routes you can simply do it with Route::get or Route::post in the routes.php file
I hope this will make it more clear for you, enjoy routing with Laravel!!!

codeigniter 2.1.4 support for http methods custom routings?

I know that codeigniter supports custom routing to another class / method
e.g.
$route['product/(:any)'] = "catalog/product_lookup";
However does it support routings based on the type of http request calling the url like in laravel ?
e.g. using get method reroute like in Laravel
Read PUT /users/X
Route::post('users/{id}','UsersController#update');
The official, production version does not. Not a single word on that in docs. But...
This feature is implemented in the development branch. It was merged from this pull request. Here's a part of the development version of documentation refering to that feature:
Using HTTP Verb in Routes
If you prefer you can use HTTP Verb (or method) to define your routing rules. This is particularly useful when building RESTful application. You can use standard HTTP Verb (GET, PUT, POST, DELETE) or custom HTTP Verb (e.g: PURGE). HTTP Verb rule is case insensitive. All you need to do is add array index using HTTP Verb rule. Example:
$route['products']['put'] = 'product/insert';
In the above example, a PUT request to URI "products" would call the "product" controller class and "insert" method.
$route['products/(:num)']['DELETE'] = 'product/delete/$1';
A DELETE request to URL with "products" as first segment and a number in the second will be remapped to the "product" class and "delete" method passing in the match as a variable to the method.
$route['products/([a-z]+)/(\d+)']['get'] = 'product/$1/$2';
A GET request to a URI similar to products/shirts/123 would call the "product" controller class and "shirt" method with number as method parameter.
Using HTTP Verb is optional, so if you want any HTTP Verb to be handled in one rule You could just write your routing rule without HTTP Verb. Example:
$route['product'] = 'product';
This way, all incoming request using any HTTP method containing the word "product" in the first segment will be remapped to "product" class.
The quick solution is to update system/core/Router.php with the changes from that specific commit: https://github.com/EllisLab/CodeIgniter/commit/af709d6ebe6ca75913d7a9eedb4fdcd76be45c50.
Also, the pull request references Pigeon library for handling advanced routing configurations.
yes you can give custom routing in codeigniter but you have to put this routing in route.php
e.g here admin is my folder name and login is controller in admin folder
$route['admin'] = "admin/login";
if you we type url http://sonedomain/CI/project/admin
then it will directly redirect me to login controller of admin folder

Categories