Tartalomjegyzék
Laravel REST API Drink példa
- Szerző: Rékási József
- Copyright © 2024, Rékási József
- Web: https://szit.hu
Szükséges szoftverek
Windowson
- PHP
- XAMP
- Composer
- Visual Studio Code vagy más szerkesztő program
- Insomnia vagy Postman
Linuxon
- PHP
- Composer
- Mariadb szerver
- Visual Studio Code vagy más szerkesztő program
- Insomnia vagy Postman
Linuxon szükséges csomagok
apt install php phpunit php-bcmath php-mbstring php-xml curl php-curl php-mysql
Ez a példaprojekt egy RestApi alkalmazást mutat be amely egy italraktár adatbázis nyilvántartását kezeli. A projekt Laravel 10 verzióval készült.
Adatbázis
drinks ( id, drink, amount, type_id, package_id )
types ( id, type )
packages ( id, package )
Projekt létrehozás
composer create-project laravel/laravel Drink
Migrációs állományok
Az adatbázisnak üresen léteznie kell, az adattáblákat a megfelelő mezőkkel a migrációs állományok fogják létrehozni.
drinks
php artisan make:migration create_drinks_table
A drinks táblában tároljuk az italokat.
public function up(): void { Schema::create('drinks', function (Blueprint $table) { $table->id(); $table->string( "drink" ); $table->integer( "amount" ); $table->foreignId( "type_id" ); $table->foreignId( "packages_id" ); $table->timestamps(); }); }
types
php artisan make:migration create_types_table
A types táblában tároljuk az italok típusait ( Bor, Sör, üdítő, …stb )
public function up(): void { Schema::create('types', function (Blueprint $table) { $table->id(); $table->string( "type" ); }); }
packages
php artisan make:migration create_packages_table
A packages táblában tároljuk az italok kiszereléseit ( Üveges, Hordós, …stb )
public function up(): void { Schema::create('packages', function (Blueprint $table) { $table->id(); $table->string( "package" ); }); }
Adattáblák létrehozása:
php artisan migrate
Modellek
Az adattáblákhoz tartozó modellek fogják kezelni az adatmozgást az alkalmazás és az adatbázis között. Fel kell venni az írható mezők listáját és szükség szerint ignorálni kell a timestamps mezőt. A model nevének meg kell egyeznie az adattábla nevével de egyes számban.
Drink
php artisan make:model Drink
class Drink extends Model { use HasFactory; protected $fillable = [ "drink", "amount", "type_id", "package_id" ]; public function type() { return $this->belongsTo( Type::class ); } public function package() { return $this->belongsTo( Package::class ); } }
Type
php artisan make:model Type
class Type extends Model { use HasFactory; protected $fillable = [ "type" ]; public $timestamps = false; public function drink() { return $this->hasMany( Drink::class ); } }
Package
php artisan make:model Package
class Package extends Model { use HasFactory; protected $fillable = [ "package" ]; public $timestamps = false; public function drink() { return $this-hasMany( Drink::class ); } }
Resources osztályok
A resources osztályok állítják össze a válaszban küldött adathalmazt. Ezeket az adatokat mi adjuk meg, mit szeretnénk látni a kimeneten. A resources osztályok neve megegyezik a model nevével.
php artisan make:resource Drink
Töltsük fela toArray() metódus tömbjét az adathalmazzal.
DrinkResource
public function toArray(Request $request): array { return [ "id" => $this->id, "drink" => $this->drink, "amount" => $this->amount, "type" => $this->type->type, "package" => $this->package->package ]; }
TypeResource
php artisan make:resource Type
public function toArray(Request $request): array { return [ "type" => $this->type ]; }
PackageResource
php artisan make:resource Package
public function toArray(Request $request): array { return [ "package" => $this->package ]; }
Kontrollerek
A kontrollerek metódusaiban történik a vezérlés, a végpontok ezekre a metódusokra mutatnak. A vezérlő osztályoknak érdemes külön könyvtárat létrehozni. Ezt könyvtárat a php artisan automatikusan létrehozza, ha nem létezik. A válaszok küldését mivel majdnem minden művelet visszatér valamilyen eredménnyel érdemes külön osztályba szervezni a kódismétlés kiküszöbölése végett.
ResponseController
php artisan make:controller Api/ResponseController
Két metódust tartalmaz, a sikeres és a hibás művletek eredményét adja vissza.
Sikeres művelet
public function sendResponse( $data, $message ) { $response = [ "sucess" => true, "data" => $data, "message" => $message ]; return response()->json( $response, 200 ); }
Hibás művelet
public function sendError( $error, $errorMessages = [], $code = 404 ) { $response = [ "success" => false, "message" => $error ]; if( !empty( $errorMessages )) { $response[ "data" ] = $errorMessages; } return response()->json( $response, $code ); }
DrinkController
php artisan make:controller Api/DrinkController
A DrinkControllert származtassuk a ResponseControllertől. A ResponseControllert és a modelt fel kell venni útvonalra. Kérjük le a drinks tábla adatait.
use App\Http\Controllers\Api\ResponseController; use App\Models\Drink;
class DrinkController extends ResponseController { public function getDrinks() { $drinks = Drink::all(); return $this->sendResponse( $drinks, "Adatok betöltve" ); } }
Teszteljük Insomnia vagy Postman programban. Ez a metódus minden adatot visszaad a táblából, de az idegen tábláknak csak az id idegen kulcsai látszanak. Kapcsoljuk hozzá a két másik táblát és nézzük meg az eredményt.
public function getDrinks() { $drinks = Drink::with( "type", "package" )->get(); return $this->sendResponse( $drinks, "Adatok betöltve" ); }
Egy ital lekérése
Most használjuk a létrehozott resources osztályt az adatok megjelenítésére. Az osztályt be kell emelni a kontrollerbe. Mivel a model és a resorces osztály neve megegyezik ezért el kell látnunk aliasszal, hogy a hivatkozás egyértelmű legyen.
use App\Http\Resorces\Drink as DrinkResource;
public function getOneDrink( $id ){ $drink = Drink::with( "type", "package" )->find( $id ); if( is_null( $drink )){ return $this->sendError( "Nincs ilyen ital" ); } return $this->sendResponse( new DrinkResource( $drink ), "Ital kiválasztva" ); }
Ital hozzáadása
Itt szükség van a kapott ital típusának és a kiszerelésének az azonosítójára. Ezeket egy másik adattáblából kell lekérni, ezt az adott adattábla saját kontrollere fogja szolgáltatni. A beérkező adatokat validálni kell. A validálást a saját request osztály végzi. Ezt fel kell venni útvonalra.
use App\Http\Requests\DrinkAddChecker;
public function addDrink( DrinkAddChecker $request ) { $request->validated(); $input = $request->all(); $drink = new Drink; $drink->drink = $input["drink"]; $drink->amount = $input["amount"]; $drink->type_id = ( new TypeController )->getTypeId( $input[ "type" ]);; $drink->package_id = ( new PackageController )->getPackageId( $input[ "package" ]); $drink->save(); return $this->sendResponse( new DrinkResource( $drink ), "Ital kiírva" );; }
Italok frissítése
Az adatokat itt is validálni kell, a szükséges azonosítokat az adattábla saját kontrollere szolgáltatja.
public function updateDrink( DrinkAddChecker $request, $id ) { $request->validated(); $input = $request->all(); $drink = Drink::find( $id ); $drink->drink = $input[ "drink" ]; $drink->amount = $input[ "amount" ]; $drink->type_id = ( new TypeController )->getTypeId( $input[ "type" ]); $drink->package_id = ( new PackageController )->getPackageId( $input[ "package" ]); $drink->update(); return $this->sendResponse( new DrinkResource( $drink ), "Ital frissítve" ); }
Ital törlése
public function deleteDrink( $id ) { $drink = Drink::find( $id ); $drink->delete(); return $this->sendResponse( new DrinkResource( $drink ), "Ital törölve" ); }
TypeController
Ez a vezérlő felelős a types tábla adatkezeléséért a megfelelő metódusokon keresztül. Az osztály szintén a ResponseControllertől öröklődik és be kell emelni a szükséges más osztályokat is.
use App\Models\Type; use App\Http\Controllers\api\ResponseController as ResponseController; use App\Http\Resources\Type as TypeResource; use App\Http\Requests\TypeAddChecker;
Típusok lekérése
public function getTypes() { $types = Type::all(); return $this->sendResponse( $types, "Típusok betöltve" ); }
Új típus felvétele
Az adatot itt is validálni kell, ezt a saját validáló osztály végzi.
public function addType( TypeAddChecker $request ) { $request->validated(); $input = $request->all(); $type = Type::create( $input ); return $this->sendResponse( new TypeResource( $type ), "Sikeres kiírás" ); }
Típus frissítése
public function updateType( TypeAddChecker $request, $id ) { $request->validated(); $input = $request->all(); $type = Type::find( $id ); $type->type = $input[ "type" ]; $type->update(); return $this->sendResponse( new TypeResource( $type ), "Típus frissítve" ); }
Típus törlése
public function deleteType( $id ) { $type = Type::find( $id ); if( is_null( $type )) { return $this->sendError( "Nincs ilyen típus" ); }else { $type->delete(); return $this->sendResponse( new TypeResource( $type ), "Típus törölve" ); } }
Típus azonosító lekérése
public function getTypeId( $typeName ) { $type = Type::where( "type", $typeName )->first(); $id = $type->id; return $id; }
PackageController
Ez a vezérlő felelős a kiszerelések adatkezeléséért. Örökölni kell a ResponseControllert és ide is be kell emelni a szükséges osztályokat.
use App\Models\Package; use App\Http\Controllers\api\ResponseController as ResponseController; use App\Http\Resources\Package as PackageResource; use App\Http\Requests\PackageAddChecker;
Kiszerelések lekérése
public function getPackages() { $packages = Package::all(); return $this->sendResponse( $packages, "Kiszerelések betöltve" ); }
Új kiszerelés felvétele
public function addPackage( PackageAddChecker $request ) { $request->validated(); $input = $request->all(); $package = Package::create( $input ); return $this->sendResponse( new PackageResource( $package ), "Sikeres kiírás" ); }
Kiszerelés frissítése
public function updatePackage( PackageAddChecker $request, $id ) { $request->validated(); $input = $request->all(); $package = Package::find( $id ); $package->package = $input[ "package" ]; $package->update(); return $this->sendResponse( new PackageResource( $package ), "Kiszerelés frissítve" ); }
Kiszerelés törlése
public function deletePackage( $id ) { $package = Package::find( $id ); if( is_null( $quantity )) { return $this->sendError( "Nincs ilyen kiszerelés" ); }else { $package->delete(); return $this->sendResponse( new PackageResource( $package ), "Kiszerelés törölve" ); } }
Kiszerelés azonosító lekérése
public function getPackageId( $packageName ) { $package = Package::where( "package", $packageName )->first(); $id = $package->id; return $id; }
Request osztályok
Ezek az osztályok felelősek a beérkező adat ellenőrzéséért. A rules() metódus ellenőrzi az adatokat, a messages() metódus a saját hibaüzenetet generálja és a failedValidation() metódus a hibaüzenetet küldi. Be kell emelni két külső osztályt.
use Illuminate\Http\Exceptions\HttpResponseException; use Illuminate\Contracts\Validation\Validator;
DrinkAddChecker
php artisan make:request DrinkAddChecker
public function rules(): array { return [ "drink" => "required", "amount" => "required", "type" => "required", "package" => "required" ]; }
public function messages() { return [ "drink.required" => "Név elvárt", "amount.required" => "Mennyiség elvárt", "type.required" => "Típus elvárt", "packages.required" => "Kiszerelés elvárt", ]; }
public function failedValidation( Validator $validator ) { throw new HttpResponseException( response()->json([ "success" => false, "message" => "Adatbeviteli hiba", "data" => $validator->errors() ])); }
TypeAddChecker
php artisan make:request TypeAddChecker
public function rules(): array { return [ "type" => "required" ]; }
public function messages() { return [ "type.required" => "Név elvárt" ]; }
public function failedValidation( Validator $validator ) { throw new HttpResponseException( response()->json([ "success" => false, "message" => "Adatbeviteli hiba", "data" => $validator->errors() ])); }
PackageAddChecker
php artisan make:request PackageAddChecker
public function rules(): array { return [ "package" => "required" ]; }
public function messages() { return [ "package.required" => "Kiszerelés elvárt" ]; }
public function failedValidation( Validator $validator ) { throw new HttpResponseException( response()->json([ "success" => false, "message" => "Adatbeviteli hiba", "data" => $validator->errors() ])); }
UserRegisterChecker
php artisan make:request UserRegisterChecker
Ez az osztály végzi a bevitt adatok ellenőrzését a megfelelő szabályokon keresztül. A rules() metódus a szabályokat tartalmazza, a messages() metódus a saját hibaüzeneteket és a failedValidation() metódus küldi a hibaüzeneteket. Emeljük be a szükséges osztályokat
use Illuminate\Http\Exceptions\HttpResponseException; use Illuminate\Contracts\Validation\Validator;
public function rules(): array { return [ "name" => "required", "email" => "required", "password" => "required", "confirm_password" => "required|same:password" ]; }
public function messages() { return [ "name.required" => "Név kötelező", "email.required" => "Email kötelező", "password.required" => "Jelszó kötelező", "confirm_password.same" => "Nem egyező jelszó" ]; }
public function failedValidation( Validator $validator ) { throw new HttpResponseException( response()->json([ "success" => false, "message" => "Adatbeviteli hiba", "data" => $validator->errors() ])); }
UserLoginChecker
php artisan make:request UserLoginChecker
Ez az osztály végzi a bejelentkezés adatainak az ellenőrzését, ide is be kell emelni a szükséges osztályokat.
use Illuminate\Http\Exceptions\HttpResponseException; use Illuminate\Contracts\Validation\Validator;
public function rules(): array { return [ "name" => "required", "password" => "required" ]; }
public function messages() { return [ "name.required" => "Név kötelező", "password.required" => "Jelszó kötelező" ]; }
public function failedValidation( Validator $validator ) { throw new HttpResponseException( response()->json([ "success" => false, "message" => "Adatbeviteli hiba", "data" => $validator->errors() ])); }
Útvonalak
Az útvonalakat az App\routes\api.php állományban rögzítsük. Az állományban fel kell venni útvonalra a kontrollereket.
use App\Http\Controllers\DrinkController; use App\Http\Controllers\api\TypeController; use App\Http\Controllers\api\QuantityController; use App\Http\Controllers\api\AuthController;
Italok
//Italok lekérése Route::get( "/drinks", [ DrinkController::class, "getDrinks" ]); //Egy ital lekérése Route::get( "/oneDrink/{id}", [ DrinkController::class, "getOneDrink" ]); //Új ital felvétele Route::post( "/addDrink", [ DrinkController::class, "addDrink" ]); //Ital frissítése Route::put( "/updatedrink/{id}", [ DrinkController::class, "updateDrink" ]); //Ital törlése== Route::delete( "/deleteDrink/{id}", [ DrinkController::class, "deleteDrink" ]);
Típusok
//Típusok lekérése Route::get( "/types", [ TypeController::class, "getTypes" ]); //Új típus felvétele Route::post( "/addtype", [ TypeController::class, "addType" ]); //Típus frissítése Route::put( "/updatetype/{id}", [ TypeController::class, "updateType" ]); //Típus törlése Route::delete( "/deletetype/{id}", [ TypeController::class, "deleteType" ]);
Kiszerelések
//Kiszerelések lekérése Route::get( "/packages", [ PackageController::class, "getPackages" ]); //Új kiszerelés felvétele Route::post( "/addpackage", [ PackageController::class, "addPackage" ]); //Kiszerelés frissítése Route::put( "/updatepackage/{id}", [ PackageController::class, "updatePackage" ]); //Kiszerelés törlése Route::delete( "/deletepackage/{id}", [ PackageController::class, "deletePackage" ]);
Azonosítás
A felhasználók kezeléséhez szükség van sanctum csomagra
composer require laravel/sanctum
A sanctum kiszolgáló beállítása:
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
A Kernel.php állományban engedélyezni kell a csoportos middleware api szekciójában a Sanctum használatát. Vegyük ki a kommentet a megfelelő sor elől.
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api'=> //\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ];
A felhasználók kezelése szintén adatbázisból történik, az ehhez szükséges adat táblák, a users és a personal_access_tokens a migráció során automatikusan létrejönnek. Szintén automatikusan létrejön a User model is, ebben a szükséges három mező: name, email, password. Ha User modelben nem találjuk, emeljük be a HasApiTokens osztályt.
use Laravel\Sanctum\HasApiTokens
A users táblát ki kell egészíteni két új mezővel amelyben a bejelentkezések számát és az esetleges kitiltás lejárati idejét tároljuk.
php artisan make:migration add_banned_data_to_users_table
public function up(): void { Schema::table('users', function (Blueprint $table) { $table->timestamp( "login_attempts" )->default( 0 ); $table->timestamp( "banned_time" )->nullable()->default( null ); }); }
UserController
Ez a vezérlő felelős a felhasználók regisztrációjáért, a bejelentkezésekért és a kijelentkezésekért. Négy metódusa van a register(), a logIn(), a logOut() és az isValidUser(). A kontrollert örököltessük a ResponseControllertől és emeljük be, illetve a még szükséges osztályokat is.
use App\Http\Controllers\Api\ResponseController as ResponseController; use Illuminate\Support\Facades\Auth; use App\Models\User; use App\Http\Requests\UserRegisterChecker; use App\Http\Requests\UserLoginChecker; use Carbon\Carbon;
Az adatokat itt is validálni kell, ezt a saját ellenőrző osztály végzi.
public function register( UserRegisterChecker $request ) { $request->validated(); $input = $request->all(); $input[ "password" ] = bcrypt( $input[ "password" ]); $user = User::create( $input ); $success[ "name" ] = $user->name; return $this->sendResponse( $success, "Sikeres regisztrácio" ); }
Ellenőrizni kell, hogy a bejelentkezni próbáló felhasználó létezik-e. Ha létezik meghívja a login() metódust, ha nem létezik hibaüzenetet ad.
public function isValidUser( UserLoginChecker $request ) { $count = User::where( "name", $request->name )->count(); if( $count != 0 ) { $data = $this->login( $request ); return $data; }else { return $this->sendError( "Azonosítási hiba", [ "Nincs ilyen felhasználó" ] ); } }
Most következik a felhasználó ellenőrzése, a felhasználónév jelszó páros. Ha a felhasználó háromszor hibásan adja meg a jelszavát, egy percre tíltásba kerül és hibaüzenetet kap. A felhasználó nevét és a tiltás idejének lejáratát emailben elküldjük egy adott címre. Sikeres bejelentkezés esetén generálni kell egy tokent ami a personal_access_tokens táblában tárolódik és nullázni kell a hibás bejelentkezés számlálókat. A hibás próbálkozások számlálását és rögzítését a BanningTimeController végzi.
public function login( UserLoginChecker $request ) { $bannedTime = null; $request->validated(); if(( Auth::attempt([ "name" => $request->name, "password" => $request->password ]))) { $bannedTime = ( new BanningTimeController )->getUserBannedTime( $request->name ); if( $bannedTime > Carbon::now( "Europe/Budapest" ) ) { return $this->sendError( "Túl sok próbálkozás", [ "nextlogin" => $bannedTime ], 429 ); } ( new BanningTimeController )->resetBannedData( $request->name ); $authUser = Auth::user(); $success[ "token" ] = $authUser->createToken( $authUser->name."Token" )->plainTextToken; $success[ "name" ] = $authUser->name; return $this->sendResponse( $success, "Sikeres bejelentkezés" ); }else { $loginCounter = ( new BanningTimeController )->getLoginAttempts( $request->name ); if( $loginCounter < 3 ) { ( new BanningTimeController )->setLoginAttempts( $request->name ); return $this->sendError( "Sikertelen azonosítás", [ "error" => "Hibás felhasználónév vagy jelszó" ]); }else if( $loginCounter == 3 && is_null( $bannedTime )) { $bannedTime = ( new BanningTimeController )->setUserBannedTime( $request->name ); $allert = ( new AllertController )->sendEmail( $request->name, $bannedTime ); return $this->sendError( "Sikertelen azonosítás", [ "error" => "Túl sok próbálkozás" ]); } } }
Kijelentkezéskor a tokent törölni kell.
public function logOut( Request $request ){ auth("sanctum")->user()->currentAccessToken()->delete(); return response()->json("Sikeres kijelentkezés"); }
BanningTimeController
Ennek a vezérlőnek a feladata kezelni a hibás bejelentkezések rögzítését és a kitiltás időintervallumának a beállítását. Emeljük be a szükséges osztályokat.
use Carbon\Carbon; use App\Models\User;
class BanningTimeController extends Controller { public function getUserBannedTime( $name ) { $user = User::where( "name", $name )->first(); return $user->banned_time; } public function getLoginAttempts( $name ) { $user = User::where( "name", $name )->first(); $loginAttempts = $user->login_attempts; return $loginAttempts; } public function setLoginAttempts( $name ) { User::where( "name", $name )->increment( "login_attempts" ); } public function setUserBannedTime( $name ) { $user = User::where( "name", $name )->first(); $banned_time = Carbon::now( "Europe/Budapest" )->addSeconds( 60 ); $user->banned_time = $banned_time; $user->save(); return $banned_time; } public function resetBannedData( $name ) { $user = User::where( "name", $name )->first(); $user->login_attempts = 0; $user->banned_time = null; $user->save(); } }
Email küldése
Két osztályra és egy nézetre van szükség, ezeket generáljuk le.
php artisan make:controller Api\AllertController php artisan make:mail AllertMail
A resources\views könyvtárban hozzuk létre a mail.blade.php állományt. Az .env állományban állítsuk be az email küldéséhez szükséges adatokat. A példában gmail fiókot használunk.
MAIL_MAILER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=a_sajat_fiokod@gmail.com MAIL_PASSWORD=a_titkos_jelszo MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS="drink@laravel.com" //Ez az emailcím fog megjelenni a levélben. MAIL_FROM_NAME="Drink projekt" // Ez a név fog megjelenni a levében.
AllertController
Ennek a vezérlőnek a feladata összeállítani az email tartalmát és itt adhatjuk meg a címzettet. Emeljük be a szükséges osztályokat.
use App\Mail\AllertMail; use Illuminate\Support\Facades\Mail;
class AllertController extends Controller { public function sendEmail( $user, $time ) { $content = [ "title" => "Felhasználó blokkolva", "user" => $user, "time" => $time ]; Mail::to( "a_sajat_email_cimed@gmail.com" )->send( new AllertMail( $content )); return false; } }
AllertMail
A konstruktorban vegyük át az összeállított adatokat. Az envelop() metódusban adhatjuk meg az email tárgyát. A content() metódusban hivatkozunk a nézetre amiben a levél kinézete van. Az attachments() metódusban van lehetőség állomány csatolására.
class AllertMail extends Mailable { use Queueable, SerializesModels; public $content; public function __construct( $content ) { $this->content = $content; } public function envelope(): Envelope { return new Envelope( subject: 'Allert Mail', ); } public function content(): Content { return new Content( view: 'mail', ); } public function attachments(): array { return []; } }
Mail nézet
Ebben a nézetben kerül összeállításra a levél kinézete, ide emeljük be a küldeni kívánt adatokat és írhatunk hozzá további szöveget.
<h1>{{ $content[ "title" ] }}</h1><br> <h3>Idő: {{ $content[ "time" ] }}</h3><br> <p><h3>{{ $content[ "user" ] }}</h3> 1 percre kitiltva túl sok sikertlen próbálkozás miatt. </p>
Védett útvonalak
A felhaszálóknak csak bejelentkezés után engedünk végrehajtani bizonyos műveleteket. Az ezekre mutató végpontokat védetté kell tenni, a middleware csomagon keresztül a Sanctum ellenőrzi jogosultságokat. Ezt a generált tokennel igazolhatjuk. A routes/api állományban állítsuk be a védett útvonalakat, vegyük fel a middleware group csoportba. Azokat az útvonalakat amelyeket nem kívánunk védeni, hagyjuk kívül.
Route::group([ "middleware" => [ "auth:sanctum" ]], function() { Route::post( "/logout", [ AuthController::class, "logOut" ]); Route::post( "/addDrink", [ DrinkController::class, "addDrink" ]); Route::put( "/updatedrink/{id}", [ DrinkController::class, "updateDrink" ]); Route::delete( "/deletedrink/{id}", [ DrinkController::class, "deleteDrink" ]); Route::post( "/addtype", [ TypeController::class, "addType" ]); Route::put( "/updatetype/{id}", [ TypeController::class, "updateType" ]); Route::delete( "/deletetype/{id}", [ TypeController::class, "deleteType" ]); Route::post( "/addpackage", [ PackageController::class, "addPackage" ]); Route::put( "updatepackage/{id}", [ PackageController::class, "updatePackage" ]); Route::delete( "/deletepackage/{id}", [ PackageController::class, "deletePackage" ]); }); Route::post( "/register", [ AuthController::class, "register" ])->middleware( "throttle:100,43200" );; Route::post( "/login", [ AuthController::class, "isValidUser" ])->middleware( "throttle:100,43200" ); Route::get( "/drinks", [ DrinkController::class, "getDrinks" ]); Route::get( "/oneDrink/{id}", [ DrinkController::class, "getOneDrink" ]); Route::get( "/types", [ TypeController::class, "getTypes" ]); Route::get( "/quantities", [ QuantityController::class, "getQuantities" ]);