I'm using laravel 8 (Laravel Framework 8.64.0) to create an API. But when make a call to an endpoint, which i define with Route::apiResource it doesn't return the result from a query, returns nothing.
routes\api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\TodoController;
/*
|--------------------------------------------------------------------------
| 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:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
//Route::get('/todos', [TodoController::class, 'index']);
Route::apiResources([
'todos' => TodoController::class,
]);
Models\Todo.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Todo extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'name',
'is_done',
'due_at',
'completed_at',
];
}
Controllers\TodoController.php
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Todo;
class TodoController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return Todo::all();
}
If I add another route:
Route::get('/todos', [TodoController::class, 'index']);
and I call it, it works.
What could possible be the problem?
You may want to try create TodoResource class extend JsonResource by running
php artisan make:resource TodoResource
then inside Todo Controller index function, replace return Todo::all(); with
return TodoResource::collection(Todo::all());
Solution why not work, remove line from
routes\api.php:
use App\Http\Controllers\Api\TodoController;
Related
I'm getting this error:
Expected status code 200 but received 404.
Failed asserting that 200 is identical to 404.
When I try to call it from my Unit Test:
<?php
namespace Tests\Unit;
use App\Models\Project;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function testTakePlace()
{
$project = Project::factory()->make();
$response = $this->getJson('controllerUserProject_takePlace', [
'project_id' => $project->id,
]);
$response
->assertStatus(200)
->assertJsonPath([
'project.status' => Project::STATES['TO_BE_REPLIED'],
]);
}
}
However, controllerUserProject_takePlace is correctly the name I gave to the route. Indeed, here is /routing/web.php:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TestConnections;
use App\Http\Controllers\ControllerUserProject;
/*
|--------------------------------------------------------------------------
| 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('/controllerUserProject_takePlace/projects/{project_id}', [ControllerUserProject::class, 'takePlace'])->name('controllerUserProject_takePlace');
The controller ControllerUserProject is correctly defined:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ControllerUserProject extends Controller
{
public function takePlace(Request $request, $project_id)
{
return [
'project_status' => Project::STATES['TO_BE_REPLIED']
];
}
}
Do you know why the use of the route returns 404 (not found)?
Your route url is '/controllerUserProject_takePlace/projects/{project_id}' while in the test you are using 'controllerUserProject_takePlace' hence the 404 error.
Also the second parameter in getJson() is array $headers so when you pass ['project_id' => $project->id] it becomes second parameter taken as $headers.
You need to supply complete url to getJson('/controllerUserProject_takePlace/projects/' . $project->id);
or
Since you have already named your route you can use the route() helper in getJson(route('controllerUserProject_takePlace', $project->id));
Change the url in your test
<?php
namespace Tests\Unit;
use App\Models\Project;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function testTakePlace()
{
$project = Project::factory()->make();
// $response = $this->getJson('/controllerUserProject_takePlace/projects/' . $project->id);
//Try using named route
$response = $this->getJson(route('controllerUserProject_takePlace', $project->id));
$response
->assertStatus(200)
->assertJsonPath([
'project.status' => Project::STATES['TO_BE_REPLIED'],
]);
}
}
How to share one method to all controllers with different DI, view and parameters? I need something like this:
public function method(Model $model)
{
$baseData = [
'model' => $model,
'route' => route('$route', [$param => $model]),
];
return view($view);
}
All controllers extend App\Http\Controllers\Controller so you can just place it there
<?php
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function method(Model $model, $route, $param, $view)
{
// Declared but not used
$baseData = [
'model' => $model,
'route' => route($route, [$param => $model]),
];
return view($view);
}
}
And use it with $this->method()
For example in HomeController
<?php
namespace App\Http\Controllers;
use App\User;
class HomeController extends Controller
{
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
$user = User::first();
return $this->method($user, 'home', 'user', 'welcome');
}
}
Now accessing domain.tld/home will return the welcome view
If you want to share function to all controller best way will make service in service folder of app.
step to make service:-
1.create service using artisan command
php artisan make:service service_name and define function that to share to all controller in your project.
after making service your have to register this service with provider.make a provider using artisan command.
php artisan make provider:provider_name and you will see 2 function register and boot
register function is used to register your created service and boot for call already register service
register service like this
public function register()
{
$this->app->bind('App\Services\servicename', function( $app ){
return new serviceclassname;
});
}
3.Go config folder ,open app.php where you will get providers array. In this provider you have to define you provider like App\Providers\providerclassname::class,
call this service in controllers like use App\Services\serviceclassname;
public function functionname(serviceclassname serviceobject)
{
serviceobject->functionname();
}
I am trying to limit my login attempts but still not working
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/home';
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
}
}
and this is ThrottlesLogin.php
protected function hasTooManyLoginAttempts(Request $request)
{
return $this->limiter()->tooManyAttempts(
$this->throttleKey($request), 3, 2
);
}
and i know in laravel 5.4 the AuthenticatesUsers call by default thethrottlesLogin but still dont limit login attempts.
and thanks
You need to use ThrottlesLogins trait in LoginController
I want to create module with number of controller like
Admin is Module name and have AdminController.
Admin module has another controller CategoryController, ProductController.
Now i wanted to use that controller as part of admin module How can i achive that using Artem-Schander/L5Modular
You have the wrong namespace in your CategoryController.php
It should be namespace App\Modules\Admin\Controllers
and not namespace App\Modules\Admin\Controllers\Category
working example:
routes.php:
Route::group(array('module' => 'Admin', 'namespace' => 'App\Modules\Admin\Controllers'), function() {
Route::resource('admin', 'AdminController');
Route::resource('category', 'CategoryController');
});
AdminController.php:
<?php namespace App\Modules\Admin\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Modules\Admin\Models\Admin;
class AdminController extends Controller {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
die('admin controller');
}
}
CategoryController.php:
<?php namespace App\Modules\Admin\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
//use App\Modules\Admin\Models\Admin;
class CategoryController extends Controller {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
die('category controller');
}
}
Here you said, you have a blank page. Check your .env file for the debug option and set it to true. Than you should have a detailed debug output.
please, could you help me a bit?
I have this route in Laravel5:
Route::get('edit_user/{userId}', [
'as' => 'editUser',
'uses' => 'Auth\UserController#editUser'
]);
But when I try to go onto url .../edit_user/19 it wont match and redirect me into /home url...
Anyway, when I use this:
Route::get('edit_user/{userId}', [
'as' => 'editUser',
function($userId) {
die($userId);
}
]);
It returns 19.
Here is also my function:
public function editUser($userId) {
die($userId);
}
Here is also part of my controller:
<?php namespace App\Http\Controllers\Auth;
use App\Models\User;
use Auth;
use Hash;
use Mail;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class UserController extends Controller {
/**
*
* #return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
}
/**
*
* show edit user form
*
* #param $id
*/
public function editUser($userId) {
die($userId);
}
Do you know any idea, where might be problem?
Thank you very much for your opinions.
EDIT:
I find out solution -> need to edit exception to auth in __construct.
This should work with the code provided.
Check the following items:
1. Do you have this code in the __construct of your UsersController?
public function __construct()
{
$this->middleware('auth');
}
If so, you need to be lagged in to edit the user.
2. Is there any route listed before edit_user/{userId} that would override this route.
Try moving it to be the very first route.
3. Is you UserController namespaced properly?
<?php
namespace App\Http\Controllers\Auth;