I’m trying to create my 1st API on Laravel 8, and want to create versioning that would look like this
https://domain/api/v1/users
My user controller looks like this
namespace AppHttpControllersApiV1;
use AppModelsUser;
class UserController
{
public function getUser(int $idUser)
{
$user = User::find($idUser);
return new AppHttpResourcesV1User($user);
}
}
in my config/app.php
i have this
'api_latest' => '1',
in my middleware (appHttpMiddlewareAPIVersion.php)
namespace AppHttpMiddleware;
use Closure;
class APIVersion
{
public function handle($request, Closure $next, $guard)
{
config(['app.api.version' => $guard]);
return $next($request);
}
}
in my kernal (app/http/kernel.php)
protected $routeMiddleware = [
// ...
'api_version' => AppHttpMiddlewareAPIversion::class,
];
in my /app/Providers/RouteServiceProvider.php
/** @var string $apiNamespace */
protected $apiNamespace ='AppHttpControllersApi';
protected function mapApiRoutes()
{
Route::group([
'middleware' => ['api', 'api_version:v1'],
'namespace' => "{$this->apiNamespace}V1",
'prefix' => 'api/v1',
], function ($router) {
require base_path('routes/api_v1.php');
});
}
and in my routes/api_v1.php
i have this
Route::middleware('api_version')->get('/user', function (Request $request) {
return $request->user();
});
I’m getting a 404 error when i type this in the browser https://domain/api/v1/users
and how do i return a json error instead of a html page for this route?
UPDATE
php artisan route:list
gives me this
+--------+----------+------------------------+----------------------+------------------------------------------------------------------------+------------+
| Domain | Method | URI | Name | Action
| Middleware |
+--------+----------+------------------------+----------------------+------------------------------------------------------------------------+------------+
| | GET|HEAD | / | | Closure
|
| | GET|HEAD | home | home | AppHttpControllersHomeController@index
| web |
| | | | |
| | GET|HEAD | login | login | AppHttpControllersAuthLoginController@showLoginForm | web |
| | | | |
| guest |
| | POST | login | | AppHttpControllersAuthLoginController@login | web |
| | | | |
| guest |
| | POST | logout | logout | AppHttpControllersAuthLoginController@logout | web |
| | GET|HEAD | password/confirm | password.confirm | AppHttpControllersAuthConfirmPasswordController@showConfirmForm | web |
| | | | |
| auth |
| | POST | password/confirm | | AppHttpControllersAuthConfirmPasswordController@confirm | web |
| | | | |
| auth |
| | POST | password/email | password.email | AppHttpControllersAuthForgotPasswordController@sendResetLinkEmail | web |
| | GET|HEAD | password/reset | password.request | AppHttpControllersAuthForgotPasswordController@showLinkRequestForm | web |
| | POST | password/reset | password.update | AppHttpControllersAuthResetPasswordController@reset | web |
| | GET|HEAD | password/reset/{token} | password.reset | AppHttpControllersAuthResetPasswordController@showResetForm | web |
| | GET|HEAD | register | register | AppHttpControllersAuthRegisterController@showRegistrationForm | web |
| | | | | | guest |
| | POST | register | | AppHttpControllersAuthRegisterController@register | web |
| | | | | | guest |
+--------+----------+------------------------+----------------------+------------------------------------------------------------------------+------------+
Advertisement
Answer
ok, do not uses middleware for changes url, only working with the routes, proof with this.
frist you must install passport or sanctum, in my case I have used passport. See the documentation continue with the installation
in app/Providers/RouteServiceProvider.php
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
{
Route::prefix('api/v1')
->middleware(['api'])
->namespace($this->namespace)
->group(base_path('routes/api/v1/api.php'));
}
In routes/api/v1/api.php
Route::prefix('/user')->group(function (){
Route::post('/login', [LoginController::class,'login']);
});
In app/Http/Controller/Auth/LoginController
to see the client’s IP is like this $request->ip();
public function login(Request $request)
{
$loginData = $request->validate([
'email' => 'email|required',
'password' => 'required'
]);
if (!auth()->attempt($loginData)) {
return response()->json(['message'=>'Datos invalidos de usuarios','success'=>false], 404);
}
$accessToken = auth()->user()->createToken('authToken')->accessToken;
return response()->json( ['success'=>true,'message'=>'Acceso consedido',
'user' => auth()->user(),
"token_type" => "Bearer",
"access_token" => $accessToken,
],200);
}
In app/Http/Controller/UserController
<?php
namespace AppHttpControllersApiV1;
use AppHttpControllersController;
use AppModelsUser;
class UserController extends Controller
{
public function getUser()
{
$users = User::get();
return response()->json(['data'=> $users]);
}
}
In routes/api/v1/api.php
if you look. I have used middleware so only authenticated users can see content.
<?php
use AppHttpControllersApiV1UserController;
use AppHttpControllersAuthLoginController;
Route::prefix('/user')->group(function (){
Route::post('/login', [LoginController::class,'login']);
Route::get('/users',[UserController::class,'getUser'])->middleware('auth:api', 'client');
});
I hope this information helps you.
λ php artisan route:list
+--------+----------+-------------------+------+----------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+-------------------+------+----------------------------------------------------+------------+
| | GET|HEAD | / | | Closure | web |
| | POST | api/v1/user/login | | AppHttpControllersAuthLoginController@login | api |
| | GET|HEAD | api/v1/user/users | | AppHttpControllersApiV1UserController@getUser | api |
| | | | | | auth:api |
| | | | | | client |
+--------+----------+-------------------+------+----------------------------------------------------+------------+