Im currently trying to create an API for my laravel project,
I have decided to move my API controllers into a subfolder of Controllers. This is the folder structure:
This is the routes file for the api:
<?php
use Illuminate\Http\Request;
use app\Http\Controllers\APIControllers;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::group(['prefix' => 'v1'], function() {
Route::get('/event_locations', 'EventLocationsAPIController#all');
});
And this is the EventLocationsAPIController:
<?php
namespace App\Http\Controllers\APIControllers;
use App\EventLocation;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class EventLocationAPIController extends Controller
{
public function all()
{
$locations = EventLocation::all();
return response()->json($locations);
}
}
When I send an GET request to /api/v1/event_locations I get the following error
Target class [App\Http\Controllers\EventLocationsAPIController] does not exist.
Any help would be appreciated!
You need to declare the namespace in route group as well.
Route::group(['prefix' => 'v1','namespace'=>'APIControllers'], function() {
Route::get('/event_locations', 'EventLocationAPIController#all');
});
you have given EventLocations plural and the controller name is singular EventLocation change the name of the controller as EventLocationAPIController in the route file.
You have to declare your nameaspace on router's group like this:
Route::namespace('APIControllers')->group(function () {
// Controllers Within The "App\Http\Controllers\APIControllers" Namespace
Route::group(['prefix' => 'v1'], function() {
Route::get('/event_locations', 'EventLocationAPIController#all');
});
});
Check Laravel docs for more info.
Related
I am using Laravel9, trying to seperate frontend and backend. I did many replace, like app\Http change to be app\Frontend\Http or app\Backend\Http.
I did the separation before, it worked. Now I cannot login or logout. But welcome page is ok. Maybe this is because the routes file ?
Auth::routes();
All content of routes/web.php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::group(
[
'prefix' => LaravelLocalization::setLocale(),
'middleware' => [ 'localeSessionRedirect', 'localizationRedirect', 'localeViewPath' ],
], function()
{
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', [App\Frontend\Http\Controllers\HomeController::class, 'index'])->name('home');
});
I also did:
composer dump-autoload
php artisan clear-compiled
php artisan route:clear
php artisan cache:clear
not working.
LoginController
<?php
namespace App\Frontend\Http\Controllers\Auth;
use App\Frontend\Http\Controllers\Controller;
use App\Frontend\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
...
Auth routes of laravel/ui package is kinda hardcoded within AuthRouteMethods class. This is the part of its method from Github repository
$namespace = class_exists($this->prependGroupNamespace('Auth\LoginController')) ? null : 'App\Http\Controllers';
$this->group(['namespace' => $namespace], function() use($options) {
// Login Routes...
if ($options['login'] ?? true) {
$this->get('login', 'Auth\LoginController#showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController#login');
}
// more code
It ensure that Auth routes will be under "default" namespace of Theme\Http\Controllers. But you may change it if wrap it in a group like
Route::group(['namespace' => 'App\Frontend\Http\Controllers'], function () {
Auth::routes();
});
This way you'll prepend group namespace to it so package will find App\Frontend\Http\Controllers\Auth\LoginController class and so on for every other auth controller
Note 1 - all controllers should be under Auth namespace and named specifically as defined in a package, you cannot change it to be like App\Whatever\LoginController or Auth\Whatever\Auth\MyLoginController - but you can do it with App\Whatever\Auth\LoginController
Note 2 - this wouldn't work with uncommented protected $namespace = 'App\\Http\\Controllers'; property within RouteServiceProvider class, as it will prepend namespace twice (you will get something like App\Http\Controllers\App\Frontend\Http\Controllers\Auth\LoginController)
I have code on api.php thats using a Dingo function and I am having trouble calling the controller because it always state that Controller is not found even though in their documentation it clearly has specified that I have to put the full path of the controller in which what is I have done.
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
// use Dingo\Api\Contract\Http\Request;
// use Dingo\Api\Facade\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
// This Will Work
// $api->get('hello', function() {
// return "hi";
// });
// Will not work
$api->get('hello', 'App\\Api\Controllers\\TestController#index');
$api->get('hi','App\\Http\\Controllers\\TestController#index');
});
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
File locations:
Error Message: Error Message: message: "Target class [app\Http\Controllers\TestController] does not exist.", status_code: 500,
What do you think I am missing here?
Casing really does matter when referencing files. I just found this out recently.
Inside hello route
namespace app\Api\Controllers;
use Dingo\Api\Http\Request;
use app\Http\Controllers\Controller;
class TestController extends Controller
{
public function index(Request $request)
{
return "hi";
}
}
Have to change the app\Http\.. to App\Http\...
Also did the same on Api.php Controllers Path
Just a reminder so when you try to use "Copy relative path" on vscode try to watch out of the naming convention.
I have installed jwt authentication & I have created a controller i.e., AuthController Inside Api Directory. I have defined the in routes/api.php as:
Route::group(['prefix'=>'v1', 'namespace' => 'Api'],function($app){
Route::get('/test', function(){
return "HEllo";
});
Route::get('test', 'AuthController#test');
});
When I hit the url as: http://localhost:8000/api/v1/test then I am getting error as Class Cotrollers\Api\AuthController does not exist.
AuthController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class AuthController extends Controller
{
public function test() {
return "Hello";
}
}
RouteServiceProvider.php:
Route::prefix('api')
// ->middleware('api')
// ->namespace($this->namespace) ->group(base_path('routes/api.php'));
Uncomment the ->namespace($this->namespace) line.
In your Route::group statement you have defined the namespace of the route group as 'Api'.
But the AuthController resides in the App\Http\Controllers namespace, and not the Api namespace.
To fix this add an Api namespace in your App\Http\Controllers and refer it there (best practice is creating a directory in the Controllers directory named Api so the directory structure follows the namespace):
AuthController.php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class AuthController extends Controller
{
public function test() {
return "Hello";
}
}
Here you need to make changes to,
App\Providers\RouteServiceProvider.php
In the RouteServiceProvider.php add
protected $namespace = 'Path\To\Controllers';
Like:
protected $namespace = 'App\Http\Controllers';
Thats it!
Please let me know if this solved your problem.
Change the Auth controller namespace definition to:
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
// you need to use your controller top of the api.php file
Route::group([
'namespace' => 'Customers', //namespace App\Http\Controllers\Customers;
'middleware' => 'auth:api', // this is for check user is logged in or authenticated user
'prefix' => 'customers' // you can use custom prefix for your rote {{host}}/api/customers/
], function ($router) {
// add and delete customer groups
Route::get('/', [CustomerController::class, 'index']); // {{host}}/api/customers/ this is called to index method in CustomerController.php
Route::post('/create', [CustomerController::class, 'create']); // {{host}}/api/customers/create this is called to create method in CustomerController.php
Route::post('/show/{id}', [CustomerController::class, 'show']); // {{host}}/api/customers/show/10 this is called to show method in CustomerController.php parsing id to get single data
Route::post('/delete/{id}', [CustomerController::class, 'delete']); // {{host}}/api/customers/delete/10 this is called to delete method in CustomerController.php for delete single data
});
I've been trying for some time to figure this out, but no solution I found was conclusive. Basically I'm trying to retrieve a list of clients based on the user logged in, but I cannot retrieve the user object anywhere in the controller except the index() function where is returns the view, and also the blade template that displays the logged in user's name.
This is my ClientController.php:
<?php
namespace App\Http\Controllers;
use App\Http\Models\Client;
use App\Http\Requests\GetClientsRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class ClientController extends Controller
{
protected $user;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->user = Auth::user();
return $next($request);
});
}
/**
* Show the clients page.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
Log::info("client user: " . print_r($this->user, 1));
return view('page');
}
public function getClients()
{
$currentUser = Auth::user();
if ($currentUser) {
$clients = Client::with('account')
->where('user_id', $currentUser->account)
->get();
$collection = collect($clients);
return response($collection->toArray());
}
}
}
The Log in the index function prints out the user object no problem - but when it's called in the getClients() function, it's empty. I also tried using this in the __construct():
$this->middleware('auth');
As per the Laravel template I was using, but whenever I call the getClients API route I always get a 401 Unauthorized error.
Here is my api.php routes file (although only currently using the getClients call) :
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::get('welcome-message', 'DashboardController#getWelcomeMessage');
Route::prefix('clients')->group(function () {
Route::get('/', 'ClientController#getClients');
Route::get('/{clientId}', 'ClientController#getClient');
Route::post('/', 'ClientController#postCreateClient');
Route::put('/{clientId}', 'ClientController#putUpdateClient');
});
And my web.php routes file:
<?php
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Auth::routes();
Route::get('/', 'HomeController#index')->name('dashboard');
Route::get('/clients', 'ClientController#index')->name('clients');
The system knows I'm logged in, because I wouldn't even be able to visit the client dashboard at all, so I don't understand why I cannot get a result from Auth::user() in the function - unless I'm using the middleware incorrectly?
You will have to use the auth:api middleware to allow API authentication.
To do so, add this middleware to your API route, omit in that case to add middleware in the __constructor.
Route::group([
'prefix' => 'clients',
'middleware' => ['auth:api']
], function(){
Route::get('/', 'ClientController#getClients');
// ... etc
});
Make sure that you have a valid access token to access your API. When using your API with a JS front-end, read about it in the Laravel docs.
Note that 'web' authentication (middleware: auth) uses a different mechanism than API authentication (middleware: auth:api) to authenticate users.
web.php file
this is my web.php file using laravel 5.4
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', [
'uses' =>'ProductController#getIndex()',
'as' =>'product.index'
]);
ProductController.php
this is my controller file using laravel5.4
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ProductController extends Controller
{
//
public function getIndex(){
return view('shop.index');
}
}
How to get rid of this error please help me.
What's wrong with it ?
You shouldn't use () in your route definition. It should be:
Route::get('/', [
'uses' =>'ProductController#getIndex',
'as' =>'product.index'
]);