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 | +--------+----------+-------------------+------+----------------------------------------------------+------------+