Laravel API Routes Return 404 - php

I am using Laravel 5.6 and I'm getting HTTP404 responses on existing routes in routes/api.php which I define as follows:
Route::middleware('auth:api')->post('/account/plan', 'Account\BillingController#updatePlan');
Route::middleware('auth:api')->put('/account/plan', 'Account\BillingController#unsubscribe');
Route::middleware('auth:api')->patch('/account/plan', 'Account\BillingController#resubscribe');
When I use axios.post() on these routes and include the _method parameter I get a 404 response on the PUT and PATCH routes. I have also tested axios.put()/axios.patch() in place of using post() with and without the inclsion of the _method parameter. I have also confirmed these are being correctly represented by artisan route:list:
| | POST | api/account/plan | | App\Http\Controllers\Account\BillingController#updatePlan | api,auth:api |
| | PUT | api/account/plan | | App\Http\Controllers\Account\BillingController#unsubscribe | api,auth:api |
| | PATCH | api/account/plan | | App\Http\Controllers\Account\BillingController#resubscribe | api,auth:api |
Example of the Axios Call:
axios.post(url,{_method:"PUT",confirm:"unsubscribe"})
.then(response => callback(response.data))
.catch(error => console.log(error))
When I define these same routes as follows they all work as intended:
Route::middleware('auth:api')->post('/account/plan', 'Account\BillingController#updatePlan');
Route::middleware('auth:api')->post('/account/unsubscribe', 'Account\BillingController#unsubscribe');
Route::middleware('auth:api')->post('/account/resubscribe', 'Account\BillingController#resubscribe');
I am able to separate endpoints by the request method on other routes I am unsure why these are creating a problem. Can someone explain why I get the 404 responses and how I can avoid them?

Since it seems you are doing evrything fine maybe by following laravel more strict conventions on defining routes you won't encounter the problem? Try like this:
Route::middleware(['auth:api'])->group(function () {
Route::post('/account/plan', 'Account\BillingController#updatePlan');
Route::put('/account/plan', 'Account\BillingController#unsubscribe');
Route::patch('/account/plan', 'Account\BillingController#resubscribe');
});

Related

route() helper function does not work with resource controller in laravel, but url() do work. Is it normal?

I have a standard resource controller registered like this:
Route::resource('/movies', \App\Http\Controllers\MovieController::class );
I checked php artisan route:list and I have the get 'movies' route.
But in blade template
Movies
does not work anymore.
And only
Movies
works.
Before that when I had:
Route::get('/movies', function () {
return view('movies');
})->name('movies');
The route method worked.
So url() method works everywhere and route() only in specific cases.
Could anyone tell me what is the main difference between those two methods?
which one should be used when?
And the main question - is it OK that the route() method does not work with resource controller, or is it something wrong with my code?
And since url() works everywhere should I just forget about route() method as unreliable?
If you look at the result of php artisan route:list you will see several routes e.g.
| | POST | movies | movies.store | App\Http\Controllers\MovieController#store | web |
| | GET|HEAD | movies | movies.index | App\Http\Controllers\MovieController#index | web |
| | DELETE | movies/{movie} | movies.destroy | App\Http\Controllers\MovieController#destroy | web |
| | PUT|PATCH | movies/{movie} | movies.update | App\Http\Controllers\MovieController#update |
route() and url() accept different values.
route() will accept route names e.g. movies.index, movies.destroy, movies.update and
url() will accept movies, movies/23.
route() will select the right methods (GET, POST, PATCH, DELETE) for you but
url() will only provide the path.

Framework PHP Route - Error 404 Not found

In Laravel, I need to edit user created by Auth/RegisterController, but using the controller that I created, example ProfileController. But when I try access by a a:href button, show 404 Error.
Code:
web.php
Route::group(['middleware' => ['auth']], function(){
Route::resource('profile', 'ProfileController')->except(['edit']);
Route::get('profile/{profile}/edit', ['as' => 'profile.edit', 'uses' => 'ProfileController#edit']);
});
Auth::routes();
app.blade.php
<a href="{{route('profile.edit',['profile'=>auth()->user()->id])}}" class="btn btn-primary">
{{auth()->user()->email}}
</a>
ProfileController
public function edit($profile)
{
$user = \App\User::findOrFail($profile);
return view('profile.edit', compact('user'));
}
List Routes
| | POST | profile | profile.store | App\Http\Controllers\ProfileController#store | web,auth,guest |
| | GET|HEAD | profile | profile.index | App\Http\Controllers\ProfileController#index | web,auth,guest |
| | GET|HEAD | profile/create | profile.create | App\Http\Controllers\ProfileController#create | web,auth,guest |
| | DELETE | profile/{profile} | profile.destroy | App\Http\Controllers\ProfileController#destroy | web,auth,guest |
| | PUT|PATCH | profile/{profile} | profile.update | App\Http\Controllers\ProfileController#update | web,auth,guest |
| | GET|HEAD | profile/{profile} | profile.show | App\Http\Controllers\ProfileController#show | web,auth,guest |
| | GET|HEAD | profile/{profile}/edit | profile.edit | App\Http\Controllers\ProfileController#edit | web,auth,guest |
Someone can help me?
Tks,
Aguiar, Adson M.
Welcome to SO!
Like #lagbox mentioned, you can just keep the
Route::resource('profile', 'ProfileController');
without the ->except() to have the exact same edit route automatically generated for you.
Furthermore, you can simplify your controller action to:
public function edit(User $profile)
{
return view('profile.edit', compact('profile'));
}
This uses type hinting to automatically have the dependency injection resolve a User instance for you, identified by the key passed in with the {profile} parameter.
You would then have to go with $profile in your profile/edit.blade.php, unless you want to do something like return view('profile.edit', ['user' => $profile]);.
It might be a good idea to name the parameters like your Models. Resource routes usually base completely on the Model's names, so profile is not a good choice for User routes. You might either use Route::resource('user', 'ProfileController') (or even UserController for that matter), or if you want to stick with profile, but want $user as a parameter, you would have to create all routes by yourself like Route::get('profile/{user}/edit', 'ProfileController').
Also, writing route('profile.edit',['profile'=>auth()->user()]) works too, and has the advantage that it would not break when the user is not authenticated.
All that said, your code should still work. Try to use a find() instead of a findOrFail() and dd($user); in the following line to make sure your route is working. If you see the dump, it is probably null, meaning the id passed is not valid, which would be really odd.
If you can post the full generated link of the anchor tag and the outcome of the dd, I'll be happy to help.

How can I generate a link to a nested resource?

The Laravel application I am working on has two resources.
The routes for the second resource are given below:
$ php artisan route:list | grep -i activity
POST | admin/procedure/{id}/activity | admin.procedure.{id}.activity.store | (...)\ProcedureActivityController#store
GET|HEAD | admin/procedure/{id}/activity | admin.procedure.{id}.activity.index | (...)\ProcedureActivityController#index
GET|HEAD | admin/procedure/{id}/activity/create | admin.procedure.{id}.activity.create | (...)\ProcedureActivityController#create
GET|HEAD | admin/procedure/{id}/activity/{activity} | admin.procedure.{id}.activity.show | (...)\ProcedureActivityController#show
PUT|PATCH | admin/procedure/{id}/activity/{activity} | admin.procedure.{id}.activity.update | (...)\ProcedureActivityController#update
DELETE | admin/procedure/{id}/activity/{activity} | admin.procedure.{id}.activity.destroy | (...)\ProcedureActivityController#destroy
GET|HEAD | admin/procedure/{id}/activity/{activity}/edit | admin.procedure.{id}.activity.edit | (...)\ProcedureActivityController#edit
I call this setup a nested resource because activities are defined under a procedure. The definition or the routes looks like this:
Route::resource('procedure', 'ProcedureController');
Route::resource('procedure/{id}/activity', 'Admin\ProcedureActivityController');
I would like to generate a link to the POST action for a new activity that belongs to procedure 3 as I would with the list-all-procedures route;
$ php artisan tinker
>>> route('admin.procedure.index')
=> "http://localhost/admin/procedure"
>>> route('admin.procedure.{id}.activity')
InvalidArgumentException with message
'Route [admin.procedure.{id}.activity] not defined.'
Is there a way to generate a link to a nested resource using the standard helpers and facades?
Your route definition for the nested resource is not quite right.
Route::resource('procedure/{id}/activity', 'Admin\ProcedureActivityController');
Should be:
Route::resource('procedure.activity', 'Admin\ProcedureActivityController');
Also I am not sure how you are getting {id} in the URI as the ResourceRegistrar will create parameters based on the resource name. Based on the definition that should be {procedure} for your first resource definition.
You should end up with a route name like admin.procedure.activity.index for the index route.
route('admin.procedure.activity.index', ['procedure' => $id]);
Laravel 5.1 - Controllers - Restful - Nested Resources
Route::resource('photos.comments', 'PhotoCommentController');
This route will register a "nested" resource that may be accessed with URLs like the following: photos/{photos}/comments/{comments}.
You should use route() with a parameter to make it work:
route('admin.procedure.{id}.activity.index', $id);

Laravel controller action returns error 404

I'm getting a 404 error when trying to access a route linked to a controller action.
I have the route defined like this in my routes.php file.
Route::controller('error', 'ErrorsController');
The ErrorsController class looks as follows.
class ErrorsController extends BaseController {
public function __construct()
{
// vacio
}
public function getIndex()
{
return View::make('error.accessdenied');
}
public function getAccessDenied()
{
return View::make('error.accessdenied');
}
}
I have a view with a link to chek if it is working properly. The link is created as follows
{{ HTML::linkAction('ErrorsController#getAccessDenied', 'Error') }}
When I click on the link the page moves to the URL 'mytestdomain.com/error/access-denied' returning an 404 error, but when I access the URL 'mytestdomain.com/error' it works perfectly.
Any idea on what I'm doing wrong?
EDIT:
Running the command php artisan routes these are the routes pointing to ErrorsController:
+--------+------------------------------------------------------------------------------------------------+------+--------------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+------------------------------------------------------------------------------------------------+------+--------------------------------------+----------------+---------------+
| | GET|HEAD error/index/{one?}/{two?}/{three?}/{four?}/{five?} | | ErrorsController#getIndex | | |
| | GET|HEAD error | | ErrorsController#getIndex | | |
| | GET|HEAD error/access-denied/{one?}/{two?}/{three?}/{four?}/{five?} | | ErrorsController#getAccessDenied | | |
| | GET|HEAD|POST|PUT|PATCH|DELETE error/{_missing} | | ErrorsController#missingMethod | | |
+--------+------------------------------------------------------------------------------------------------+------+--------------------------------------+----------------+---------------+
Only the sencond and the fourth ones are working.
It looks as though specifying the route in the way you have won't work. This type of routing only works for RESTful requests. See >http://laravel.com/docs/4.2/controllers#restful-resource-controllers>.
You might have to explicitly specify the route using Route::get/post.
Somehow I found the problem.
For some reason, my apache server doesn't rewrite mytestdomain.com/error/ * route. Probably is something related with the word error and the apache module mod_rewrite.
Anyway, defining the route as follows solves the problem.
Route::controller('fail', 'ErrorsController');

Laravel Using controller Route

i have resource in route and that work correctly and i want to change that to Route::controller.
but after define that i get error in php artisan route :
+--------+------------------------------------+-----------+---------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+------------------------------------+-----------+---------------------------------+----------------+---------------+
| | GET index | index | Closure | | |
| | GET admin/index | dashboard | Closure | | |
| | GET logout | logout | Closure | | |
| | POST auth | auth | Closure | csrf | |
| | GET login | login | Closure | | |
| | GET admin/admin/profile/{_missing} | | ProfileController#missingMethod | | |
+--------+------------------------------------+-----------+---------------------------------+----------------+---------------+
my Current route is:
Route::resource('profile' , 'ProfileController', array('as'=>'profile') );
and i want to change that to :
Route::controller('admin/profile', 'ProfileController', array('index'=>'profile.index') );
how to resolve this problem?
This is not an error, Resource and Controller routes are completely different things.
Resource routes have a predefined list of routes (index, create, store, delete, update). If you don't have the method set in your controller it will still work, unless someone hit that route.
Controller routes relies on your controller methods:
public function getIndex() {}
public function getCreate() {}
public function postStore() {}
Methods names are predefined as
<http method><your action name>()
If those methods are not present in your controller, Laravel will not show them in your routes list.
So, just create a
public function getIndex() {}
In your controller and run
php artisan route
Again.
Use :
Route::resource('profile, 'ProfileController', array('as' => 'profile', 'names' => array('index' => 'profile.index')));
Instead of either the routes above.

Categories