Tempo di lettura: 75 minuti
Angular e Laravel:Creare un’API con Laravel
API sta per Application Program Interface . In poche parole, un’API è un’interfaccia che si utilizza per comunicare con le applicazioni.
L’API agisce proprio come un middleware . Quando inviamo richieste a un’API, essa controlla le richieste. Se le richieste sono consentite, i dati verranno restituiti. Vengono restituite anche risposte adeguate per farci conoscere il risultato delle nostre richieste.
Utilizzando le API, possiamo creare efficacemente un servizio di backend che supporta molti tipi di applicazioni. Gli sviluppatori possono cambiare frequentemente l’aspetto delle loro app senza preoccuparsi di rompere le app.
Laravel: le REST API
REST sta per Representational State Transfer . È uno stile di architettura web. Fondamentalmente, REST è solo un insieme di accordi e vincoli su come i componenti dovrebbero lavorare insieme.
Quando le API utilizzano l’architettura REST, vengono chiamate REST API ( note anche come RESTful APIs).
Una tipica REST API ha i seguenti vincoli :
- Client – server : server (back end) e client (front end) possono essere sviluppati indipendentemente.
- Stateless : lo stato della sessione deve essere archiviato sul client. I dati del client non devono essere archiviati sul server tra le richieste.
- Memorizzabile nella cache: il client può memorizzare nella cache le risposte per migliorare la scalabilità e le prestazioni.
La REST API utilizza le richieste HTTP per comunicare con i server. Ogni richiesta specifica un certo verbo HTTP nell’intestazione della richiesta, come ad esempio:
GET /posts HTTP/1.1
Esistono più richieste HTTP , ma i più popolari per la creazione di REST API sono:
- GET –ottenere
- POST –inviare
- PUT/PATCH –inserire in caso di modifica
- DELETE –cancellare
Cos’è Laravel?
Laravel è un framework PHP orientato alla programmazione ad oggetti ed al pattern architetturale MVC (che se non conoscete consiglio caldamente di studiarvi) e all’eliminazione di uno dei nostri peggiori nemici, lo spaghetti code. Presenta, inoltre, un comodo sistema di bundles per “pacchettizzare” i nostri software (parliamo quindi di HMVC), in modo tale da creare applicazioni sempre più sofisticate e al tempo stesso facilmente manutenibili.
La sua storia comincia nel 2011, quando Taylor Otwell decide di “rendere lo sviluppo web più facile e divertente, perché è quello che amo fare”. Da allora di strada ne è stata fatta, nonostante siano passati solo poco meno di due anni…
Bhe! Se non conoscete il framework leggetevi prima questo articolo dove spiego passo passo di cosa si tratta e come installare l’occorrente.
Installare Laravel
Come fatto per Angular createvi una directory a piacere , quindi fate click con il tasto destro del mouse ed apritela con Git bash, poi digitate:
laravel new angularbook
ecco se vi restituisse un errore del genere dipende dal loro server:
In RequestException.php line 113: Server error: `GET http://cabinet.laravel.com/latest.zip` resulted in a `52 2 Origin Connection Time-out` response: <html> <head><title>522 Origin Connection Time-out</title></head> <body bgcolor="white"> <center><h1>522 Origin Conne (truncated...)
quindi in alternativa installatelo da composer:
composer create-project laravel/laravel myProject
in questo modo andremo ad installare l’ultima versione del framework.
Nel caso in cui avessimo necessità di scaricare una versione specifica basterebbe digitare:
composer create-project laravel/laravel="5.1.*" myProject
ecco in questo caso scaricherei la versione 5.1 ad esempio.
Bene ora attendiamo qualche istante perchè venga scaricato il pacchetto. Una volta fatto spostatevi all’interno della directory dello stesso e digitate da terminale:
cd angularbook/ php artisan serve
se tutto è andato bene ora all’indirizzo http://127.0.0.1:8000/ dovreste vedere:
ora verifichiamone la versione digitando da terminale ed all’interno sempre della directory principale:
php artisan --version
al momento della stesura di questo tutorial la versione in essere è:
php artisan --version Laravel Framework 8.14.0
Grandi!!
Realizzare il database con Xampp Server
Benissimo ( dando per scontato che vi siete letti l’articolo su Laravel), ora avviate Xampp Server .
Una volta avviato, nel menu a destra aprite la shell e digitate:
mysql -u root -p
una volta che vi chiede la password non inserite niente e date invio:
Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 8 Server version: 10.4.14-MariaDB mariadb.org binary distribution Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]>
ok abbiamo effettuato l’accesso a MySql.
Ora digitate:
CREATE DATABASE angularbook;
se restituisce questo:
Query OK, 1 row affected (0.102 sec)
è a posto. Quindi verifichiamo:
... MariaDB [(none)]> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | angular_db | | angularbook | | information_schema | | laravel_jwt | | laravelangular_db | | mysql | | performance_schema | | phpmyadmin | | student_db | | test | | ticket_data | | trivia | +--------------------+ 12 rows in set (0.199 sec) ...
come potete vedere il nostro database si trova nella lista per cui ottimo direi.
Ora chiudete la shell:
exit
due volte.
Laravel: connettere l’Applicazione al database
Aprite l’applicazione con il vostro editor preferito, quindi aprite il file .env e configuriamo i parametri d connessione con il nostro db:
... DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel DB_USERNAME=root DB_PASSWORD= ...
in questa sezione andiamo a modificare semplicemente il nome del db, visto che l’username è corretto e non abbiamo password:
... DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=angularbook DB_USERNAME=root DB_PASSWORD= ...
perfetto!!
Realizza l’API con laravel
Visto che si tratta di un’autenticazione ci occorre una tabella nel db relativa agli utenti che si registrano e si loggano. Per tale operazione ci è venuto incontro Laravel in quanto di default crea sia la migration che il model relativi ad essi:
app/models/User.php
<?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use HasFactory, Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'email_verified_at' => 'datetime', ]; }
quindi database/migrations/2014_10_12_000000_create_users_table.php:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }
a questo punto allora non ci resta che realizzare la tabella nel database, da terminale all’interno della directory del progetto digitate:
lucio@LENOVO MINGW64 /e/TODO-ANGULAR/angular-laravel/angularbook $ php artisan migrate
se restituisce:
Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table (338.08ms) Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table (707.91ms) Migrating: 2019_08_19_000000_create_failed_jobs_table Migrated: 2019_08_19_000000_create_failed_jobs_table (358.15ms)
è andato a buon fine e ciò conferma anche la corretta connessione al db, ottimo direi!!!
Ora se aprite phpMyAdmin vi troverete con un nuovo database ed una serie di tabelle realizzate da Laravel per noi.
Realizza l’End Point
Creiamo subito il controller relativo agli User, da terminale digitate:
php artisan make:controller UserController --resource
aggiungendo il flag resource abbiamo aggiunto anche una serie di funzionalità che ci occorrerano ai fini della registrazione (quindi aggiunta utente), del login, visualizzare l’utente, ecc…
se aprite app/controllers/UserController.php:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { // } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { // } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { // } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { // } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { // } }
vedete che vi sono una serie di metodi:
- index–ritorna la lista degli utenti
- create –crea l’utente
- update –lo modifica/aggiorna
- delete– lo elimina
Le routes
Laravel ha una funzionalità chiamata middleware groups . Quando inserisci le rotte nel file web.php , egli applica il web middleware group a tutte le rotte.
Apriamo il file app / Http / Kernel.php :
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ 'throttle:60,1', 'bindings', ], ];
Come puoi vedere, il middleware groups ‘ web’ =>… si trova all’interno di questo file. Più in basso potete notare anche anche ‘api’ =>… Quando si creano API con Laravel , è meglio utilizzare quest’ultimo gruppo middleware, in modo tale da non dover utilizzare tipo Sessioni ,CSRFToken, Cookie, ecc…
Le rotte normali potete realizzare tranquillamente all’interno del gruppo ‘web’.
Allora aprite il file routes/api.php ed aggiungete il percorso:
Route::resource('users', UserController::class);
Ovviamente ricordati di importare il controller UserController.php.
Per assicurarti di avere tutti i percorsi relativi all’utente digita da terminale il seguente comando:
php artisan route:list
ricevi:
+--------+-----------+-----------------------+---------------+------------------ ---------------------------+------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+-----------+-----------------------+---------------+------------------ ---------------------------+------------+ | | GET|HEAD | / | | Closure | web | | | GET|HEAD | api/user | | Closure | api | | | | | | | auth:api | | | GET|HEAD | api/users | users.index | App\Http\Controll ers\UserController@index | api | | | POST | api/users | users.store | App\Http\Controll ers\UserController@store | api | | | GET|HEAD | api/users/create | users.create | App\Http\Controll ers\UserController@create | api | | | GET|HEAD | api/users/{user} | users.show | App\Http\Controll ers\UserController@show | api | | | PUT|PATCH | api/users/{user} | users.update | App\Http\Controll ers\UserController@update | api | | | DELETE | api/users/{user} | users.destroy | App\Http\Controll ers\UserController@destroy | api | | | GET|HEAD | api/users/{user}/edit | users.edit | App\Http\Controll ers\UserController@edit | api | +--------+-----------+-----------------------+---------------+------------------ ---------------------------+------------+
cioè tutti i metodi e percorsi disponibili.
Il Seeder: popolare la tabella
Bhe prima di proseguire ritengo sia il caso di inserire qualche dato nella nostra tabella in modo tale da poter provare l’Api. Laravel ci viene incontro mediante il Seeder, cioè una classe che popola le tabelle con dati finti durante la fase di test/sviluppo.
Innanzitutto creiamo la classe , da terminale digitate:
php artisan make:seeder UsersTableSeeder
quindi apritelo su database/seeders/UsersTableSeeder.php e modificate il metodo run:
public function run() { $faker = Faker::create(); $usersPsw = array( "demodemo", "123456", "testtest" ); foreach($usersPsw as $userPsw) { User::create([ 'name' => $faker->firstName .' '. $faker->lastName , 'email' => $content = $faker->email, 'password' => $userPsw ]); } }
come noterete utilizzo il Faker di Fzainotto, se volete saperne di più cliccate qui.
Ricordatevi di importare la classe User e Faker:
use App\Models\User; use Faker\Factory as Faker;
quindi per attivarlo aprite database/seeders/DatabaseSeeder.php e modificate come di seguito:
public function run() { // \App\Models\User::factory(10)->create(); $this->call(UsersTableSeeder::class); }
quindi da terminale lanciamolo:
php artisan db:seed
response ok:
$ php artisan db:seed Seeding: Database\Seeders\UsersTableSeeder Seeded: Database\Seeders\UsersTableSeeder (744.51ms) Database seeding completed successfully.
ecco la tabella aggiornata sul db:
ottimo direi!!!
Siamo pronti per farci restituire i dati, quindi per implementare il controller e nello specifico il metodo index che si preoccupa di inviarci i dati mediante metodo Get, aprite app/http/controllers/UserController.php e modificate il metodo index:
public function index() { $users = User::all(); return $users; }
ricordatevi di importare il model User 😉
Se cliccate su http://127.0.0.1:8000/api/users vi troverete i dati in formato json 🙂 🙂
se volete potete utilizzare postman, ottimo tool per testare le REST API
eccolo:
abbiamo realizzato il nostro primo END POINT in LARAVEL!!
Tuttavia dobbiamo ancra fare una piccola modifica, aprite il api.php e modificate da così:
... Route::resource('users', UserController::class); ...
Route::group(['prefix' => 'v1'], function(){ Route::resource('users', UserController::class); });
in poche parole ho aggiunto un prefisso al nostro END POINT, in modo tale da averlo personalizzato e da poter ,quindi, realizzare altri END POINT con altri prefissi.
Quindi cambiate il collegamento, ora sarà:
http://127.0.0.1:8000/api/v1/users
Gestire i CORS
CORS sta per Cross-Origin Resource Sharing , è un sistema che consente ai browser moderni di inviare e ricevere dati limitati (immagini, caratteri, file, ecc.) da un dominio diverso da quello che effettua la richiesta.
In poche parole, se non abilitiamo CORS , non possiamo accedere alla nostra API da altre applicazioni.
Esistono diversi modi per abilitare i CORS negli END POINT, in questo tutorial lo faremo personalizzato senza la necessità di attingere ad altre librerie, a mio avviso è il modo più semplice da capire.
Aggiunta di CORS utilizzando un middleware personalizzato
Aprite il terminale e digitate:
php artisan make:middleware Cors
ora aprite il file app / Http / Kernel.php ed aggiungete il collegamento al CORS creato:
... protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'cors' => \App\Http\Middleware\Cors::class, ]; ...
non dimentichiamoci di modificare il CORS creato, apritelo su app / Http / Middleware / Cors.php:
public function handle(Request $request, Closure $next) { return $next($request); }
modificate:
public function handle($request, Closure $next) { return $next($request) ->header('Access-Control-Allow-Origin', '*') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); }
benissimo ora dobbiamo abilitarlo sulle rotte API, aprite il file routes/api.php:
Route::group(['prefix' => 'v1'], function(){ Route::resource('users', UserController::class); });
modificate:
Route::group(['prefix' => 'v1', 'middleware' => 'cors'], function(){ Route::resource('users', UserController::class); });
ho semplicemente aggiunto un’altra chiave middleware con valore cors.
Per il momento con Laravel abbiamo terminato ,vediamo come collegarci con esso lato front-end, per cui riapriamo Angular.