Tartalomjegyzék
Laravel API kezdés
- Szerző: Sallai András
- Copyright © Sallai András, 2021, 2023
- Web: https://szit.hu
Projekt
Hozzuk létre a projektet:
composer create-project laravel/laravel emp
Lépjünk be könyvtárba, majd indítsuk el a szervert:
cd emp php artisan serve
Adatbázis
Használhatunk többféle adatbázis, itt most SQLite-t fogunk használni.
A database könyvtárban hozzuk létre az SQLite adatbázist, database.sqlite néven, egy üres fájl formájában:
- database/database.sqlite
Szerkesszük a .env fájlt, írjuk bele milyen adatbázist használunk.
- .env
DB_CONNECTION=sqlite
A MySQL-ra vonatkozó beállításokat tegyük megjegyzésbe.
Routes
A routes vagy magyarul útválasztásban határozzuk meg, milyen végpontokat érhetünk el, és a végpontokat elérve, mi kell történjen.
Szerkesszük a routes/api.php fájlt:
- routes/api.php
<?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 and all of them will | be assigned to the "api" middleware group. Make something great! | */ Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); });
A két use kezdetű sor lehetővé teszik hogy használjuk a Request és a Route osztályokat.
A Route::middleware() függvényhívással kezdődő sor egy útválasztási bejegyzés. Töröljük, vagy tegyük megjegyzésbe.
Vegyünk fel egy saját útválasztó bejegyzést, GET metódussal:
- routes/api.php
//... Route::get('/employees', function(){ return 'employees'; });
A /employees végpontot határoztuk meg és egy névtelen függvényben, az 'employees' szóval térünk vissza.
Ellenőrzés
Használjuk egy HTTP klienst a teszteléshez. Lehet egy böngésző, az Insomnia, vagy a curl parancssoros program.
Készítsünk egy GET kérést a következő címre:
http://localhost:8000/api/employees
Gyakorlat
- Készítsünk legalább három másik végpontot, GET metódussal, különféle üzenetekkel.
Dolgozók modell és tábla
Hozzuk létre a dolgozók táblát gyártó PHP osztályt:
php artisan make:model Employee --migration
A --migration kapcsoló, létrehozza a migrációs fájlokat, amiből leképezhető az adatbázis tábla. A Laravel alapértelmezetten tartalmaz néhány migrációs táblát, ezek szükségesek a működéshez.
A migrációs fájlok a database/migrations könyvtárban vannak.
Szerkesszük a database/migrations/*create_employees_table.php fájlt. A * helyén az aktuális dátum szerepel.
- database/migrations/*create_employees_table.php
//... public function up() { Schema::create('employees', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('city'); $table->decimal('salary', 5, 2); $table->timestamps(); }); } //...
Ezt követően a táblák elkészíthetők
Hozzuk létre a táblákat:
php artisan migrate
További lehetőségek a migrációs fájlokban:
$table->increments('id'); $table->boolean('done'); $table->tinyInteger('status')->default('1');
Tábla frissítése
Ha szeretnénk javítani a migrációs állományt, szükség van a migráció újabb futtatására. Ez a :refresh utótaggal tehetjük meg.
php artisan migrate:refresh
Útválasztás javítása
Vegyük használatba az útválasztóban az Employee osztályt:
- routes/api.php
use App\Models\Employee; //... Route::get('/employees', function(){ return Employee::all(); });
Ellenőrizzük Insomnia-ban:
- Metódus: GET
A tábla üres, de 200-s kódot kell kapjunk.
A post metódus
Szeretnénk új dolgozót felvenni. Ehhez engedélyezzük a name, city és salary mezők megadását:
- app/Models/Employee.php
//... class Employee extends Model { use HasFactory; protected $fillable = [ 'name', 'city', 'salary' ]; }
A routingban beállítunk egy dolgozót:
- routes/api.php
//... Route::post('/employees', function(){ return Employee::create([ 'name' => 'Rágó Ferenc', 'city' => 'Szolnok', 'salary' => 2873000 ]); });
Ellenőrizzük egy POST kéréssel az Insomnia-ban. Nézzük meg az adatbázisban az új dolgozót.
Így most, mindig ezt a felhasználót fogja felvenni. A következő fejezetben megoldjuk, hogy a bejövő HTTP kérésből vegyük a dolgozó adatait.
A dolgozó kontroller
Hozzunk létre egy Employee nevű kontrollert:
php artisan make:controller EmployeeController --resource --api
Kapcsolók:
- A --resource hatására létrejönnek az alapértelmezett metódusok.
- A --api hatására nem jön létre create és edit metódus.
A create és edit metódusok nem szükségesek REST API készítése során.
Szerkesszük az EmployeeController.php fájlt. Szükség van az Employee modellre, vegyük azt használatba:
- app/Http/Controller/EmployeeController.php
//... use App\Models\Employee;
Az index függvényben kérjük le az összes dolgozó adatait:
public function index() { return Employee::all(); }
Állítsuk be az útválasztás:
- routes/api.php
use App\Http\Controllers\EmployeeController; //... Route::get('/employees', [EmployeeController::class, 'index']);
A [EmployeeController::class, 'index'], azt jelenti, az EmployeeController osztályon belül szeretnénk az index metódust hívni, ha valaki a /employees végpontra hivatkozik.
Ellenőrizzük API klienssel.
Ha szeretnénk dolgozót tárolni egy store() nevű metódust hozunk létre.
Írjuk meg a store függvényt:
- app/Http/Controller/EmployeeController.php
//... public function store(Request $request) { return Employee::create($request->all()); }
Írjunk hozzá útválasztást:
- routes/api.php
use App\Http\Controllers\EmployeeController; //... Route::get('/products', [EmployeeController::class, 'index']); Route::post('/employees', [EmployeeController::class, 'store']);
Teszteljük API klienssel. JSON tartalmat küldünk. Insomnia esetén figyeljük meg a „Header” fülön, hogy beállításra kerül a „Content-Type” „application/json” fejléc adat.
Válaszkód küldése
- app/Http/Controller/EmployeeController.php
//... public function store(Request $request) { $employees = Employee::create($request->all()); return response($employees, 201); }
A sikeres létrehozást 201-s válaszkóddal jelezzük.
Validáció beállítása
- app/Http/Controller/EmployeeController.php
//... public function store(Request $request) { $request->validate([ 'name' => 'required', 'salary' => 'required' ]); $employees = Employee::create($request->all()); return response($employees, 201); }
Egyetlen dolgozó lekérdezése
- app/Http/Controller/EmployeeController.php
//... public function show($id) { return Employee::find($id); }
Írjunk hozzá útválasztást:
- routes/api.php
Route::get('/products/{id}', [EmployeeController::class, 'show']);
A végpont után írt {id} az show() metódusban elérhető paraméterként a kontrollerben.
Dolgozó módosítása
- app/Http/Controller/EmployeeController.php
//... public function update(Request $request, $id) { $employee = Employee::find($id); $employee->update($request->all()); return $employee; }
Írjunk hozzá útválasztást:
- routes/api.php
//... Route::put('/employees/{id}', [EmployeeController::class, 'update']);
Ellenőrizzük API klienssel.
Dolgozó törlése
- app/Http/Controller/EmployeeController.php
//... public function destroy($id) { return Employee::destroy($id); }
Írjunk hozzá útávlasztást:
- routes/api.php
//... Route::delete('/employees/{id}', [EmployeeController::class, 'destroy']);
Ellenőrizzük API klienssel.
Siker esetén 1-el tér vissza.
Összes erőforrás
Az összes CRUD műveletet egyetlen útválasztó bejegyzéssel megoldhatjuk:
- routes/api.php
use App\Http\Controllers\EmployeeController; //... Route::resource('/employees', EmployeeController::class); /* Route::get('/products', [EmployeeController::class, 'index']); Route::post('/employees', [EmployeeController::class, 'store']); Route::get('/products/{id}', [EmployeeController::class, 'show']); Route::put('/employees/{id}', [EmployeeController::class, 'update']); Route::delete('/employees/{id}', [EmployeeController::class, 'destroy']); */
Ellenőrizzük, milyen router információk vannak:
php artisan route:list
Ellenőrizzük API klienssel. Cím:
http://localhost:8000/api/employees/2
Keresés
- app/Http/Controller/EmployeeController.php
//... public function search($name) { return Employee::where('name', 'like', '%'.$name.'%')->get(); }
Routing szerkesztése:
- routes/api.php
use App\Http\Controllers\EmployeeController; //... Route::get('/employees/search/{name}', [EmployeeController::class, 'search']);
Ellenőrizzük API klienssel.
Például:
http://localhost:8000/api/employees/search/László
Sanctum
A csomagok (package) között található a Sanctum:
- routes/api.php
use App\Http\Controllers\EmployeeController; //... Route::resource('/employees', EmployeeController::class); // Route::get('/employees/search/{name}', [EmployeeController::class, 'search']); // Route::get('/employees', [EmployeeController::class, 'index']); // Route::post('/employees', [EmployeeController::class, 'store']); Route::group(['middleware' => ['auth:sanctum']], function () { Route::get('/employees/search/{name}', [EmployeeController::class, 'search']); }); Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); });
Ellenőrizzük:
http://localhost:8000/api/employees/search/László
A következő hibát kapjuk:
Route [login] not defined.
Állítsuk be fejlécben → „Header” fülön:
Accept application/json
A következő választ kapjuk:
{ "message": "Unauthenticated." }
Auth kontroller
php artisan make:controller AuthController
- app/Http/Controllers/AuthController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; use Illuminate\Http\Response; use Illuminate\Support\Facades\Hash; use Illuminate\Support\facades\Auth; class AuthController extends Controller { public function register(Request $request) { $fields = $request->validate([ 'name' => 'required|string', 'email' => 'required|string|unique:users,email', 'password' => 'required|string|confirmed' ]); $user = User::create([ 'name' => $fields['name'], 'email' => $fields['email'], 'password' => bcrypt($fields['password']) ]); $token = $user->createToken('sajatToken')->plainTextToken; $response = [ 'user' => $user, 'token' => $token ]; return response($response, 201); } public function login(Request $request) { if( Auth::attempt([ "name" => $request->name, "password" => $request->password ])) { $authUser = Auth::user(); $success[ "token" ] = $authUser->createToken( "myapptoken" )->plainTextToken; $success[ "name" ] = $authUser->name; return response( $success); }else { return response( "Hiba! A bejelentkezés sikertelen", [ "error" => "Hibás adatok" ]); } } public function logout( Request $request ) { auth( "sanctum" )->user()->currentAccessToken()->delete(); return response()->json('Kijelentkezve'); } }
Az AuthController tartalmát, akár be is másolhatjuk, de van egy hivatkozás User osztályra, ezért ne felejtsük el használatba vennei:
use App\Models\User; use Illuminate\Http\Response; use Illuminate\Support\Facades\Hash; use Illuminate\Support\facades\Auth; //...
Regisztrációnál a jelszó elkérhető kétszer:
$validator = Validator::make( $request->all() , [ "name" => "required", "email" => "required", "password" => "required", "confirm_password" => "required|same:password", ]);
Regisztráció
Az api számára is fel kell vennünk felhasználókat az azonosításhoz. Használhatunk hozzá egy REST API klienst, például Insomnia.
Fejléc:
Accept application/json
Ezt küldjük:
{ "name": "mari", "email": "mair@zold.lan", "password": "titok", "password_confirmation": "titok" }
Eredmény:
{ "user": { "name": "mari", "email": "mari@zold.lan", "updated_at": "2021-11-24T19:57:43.000000Z", "created_at": "2021-11-24T19:57:43.000000Z", "id": 3 }, "token": "3|7eBr5iAUPgqQz3lxIFgC72Yh3ERO76g1MyuHNOGD" }
Keresés azonosítással
Insomnia-ban:
- Auth fül
- Kiválasztjuk: Bearer
- Token: 3|7eBr5iAUPgqQz3lxIFgC72Yh3ERO76g1MyuHNOGD
- [Send]
Útválasztás
Route::post('/register', [AuthController::class, 'register']); Route::post('/login', [AuthController::class, 'login']);
Kilépés
- app/Http/Controllers/AuthController.php
//... public function logout(Request $request) { auth()->user()->tokens()->delete(); return [ 'message' => 'Logged out' ]; }
Útválasztás:
- routes/api.php
Route::group(['middleware' => ['auth:sanctum']], function () { Route::get('/employees/search/{name}', [EmployeeController::class, 'search']); Route::post('/logout', [AuthController::class, 'logout']); });
Teszteléshez:
http://localhost:8000/api/logout