Salta al contenuto principale

Come creare una RESTful api con Laravel

Profile picture for user luca77king

Nel mondo moderno dello sviluppo web, tutto ruota attorno alle API. Le app non vivono più isolate: parlano tra loro, condividono dati, sincronizzano utenti e gestiscono servizi esterni. Un frontend in Angular o React, un’app mobile in Flutter o Swift, oppure un microservizio in Node: tutti hanno bisogno di un backend solido e flessibile. È qui che entra in gioco Laravel, il framework PHP che da anni detta legge per eleganza, produttività e coerenza.

Laravel ti permette di costruire API RESTful in modo pulito, scalabile e sicuro, senza dover reinventare nulla. In questa guida vedremo come creare da zero un’API moderna, con autenticazione basata su Laravel Sanctum, validazione automatica, trasformazione dati tramite API Resource, gestione delle relazioni e risposta JSON ottimizzata.

L’obiettivo sarà creare una mini API per gestire tutorial con sottotutorial (relazioni padre-figlio), dotata di autenticazione e protetta da token. Il tutto con codice pulito, performante e facilmente estendibile.

Preparazione del progetto

La prima cosa da fare è creare un nuovo progetto Laravel. Se hai Composer installato, puoi farlo con un singolo comando:

composer create-project laravel/laravel tutorial-api
cd tutorial-api

Una volta installato, esegui le migrazioni base:

php artisan migrate

Laravel ti fornirà già una struttura ordinata: nel file routes/api.php andrai a definire tutte le rotte della tua API, che saranno automaticamente caricate con il middleware api.

Configurare Laravel Sanctum per l’autenticazione

Le API moderne devono essere protette, ma non sempre hai bisogno di un sistema JWT complesso. Laravel Sanctum è la soluzione più elegante: semplice, sicura e perfettamente integrata.

Installa Sanctum:

composer require laravel/sanctum
php artisan migrate

Poi registra il middleware nel kernel API:

// app/Http/Kernel.php

protected $middlewareGroups = [
    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

Nel modello User, aggiungi il trait necessario:

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
}

Ora puoi gestire token personali, login e logout in modo automatico, senza configurazioni complesse.

Creare il modello e la migrazione

Immaginiamo una struttura di tutorial nidificati. Ogni tutorial può avere dei “figli” e un ordine definito grazie a spatie/eloquent-sortable. Installiamolo:

composer require spatie/eloquent-sortable

Creiamo il modello:

php artisan make:model Tutorial -m

E modifichiamo la migrazione:

Schema::create('tutorials', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->foreignId('parent_id')->nullable()->constrained('tutorials')->cascadeOnDelete();
    $table->integer('order_column')->default(0);
    $table->timestamps();
});

Ecco il modello:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;

class Tutorial extends Model implements Sortable
{
    use SortableTrait;

    protected $fillable = ['title', 'parent_id', 'order_column'];

    public $sortable = [
        'order_column_name' => 'order_column',
        'sort_when_creating' => true,
    ];

    public function childs()
    {
        return $this->hasMany(Tutorial::class, 'parent_id')->with('childs');
    }

    public function parent()
    {
        return $this->belongsTo(Tutorial::class, 'parent_id');
    }
}

Definire le API Resource

Laravel Resource serve per controllare il formato JSON restituito dall’API, in modo coerente e pulito.
Creiamone una per i tutorial:

php artisan make:resource TutorialResource

Poi la modifichiamo:

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Models\Tutorial;

/**
 * @mixin Tutorial
 */
class TutorialResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'is_first_in_order' => $this->isFirstInOrder(),
            'is_last_in_order' => $this->isLastInOrder(),
            'childs' => TutorialResource::collection($this->whenLoaded('childs')),
        ];
    }
}

L’uso del @mixin serve solo a far capire a PHPStorm che $this è un modello Tutorial.
La chiamata TutorialResource::collection() permette di trasformare automaticamente tutti i figli in risorse a loro volta, generando JSON strutturato in modo ricorsivo.

Il controller RESTful

Laravel fornisce generatori di controller RESTful già pronti. Creiamolo:

php artisan make:controller Api/TutorialController --api

Il controller sarà così:

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Resources\TutorialResource;
use App\Models\Tutorial;
use Illuminate\Http\Request;

class TutorialController extends Controller
{
    public function index()
    {
        $tutorials = Tutorial::with('childs')->ordered()->get();
        return TutorialResource::collection($tutorials);
    }

    public function store(Request $request)
    {
        $validated = $request->validate(['title' => 'required|string|max:255']);
        $tutorial = Tutorial::create($validated);
        return new TutorialResource($tutorial);
    }

    public function show(Tutorial $tutorial)
    {
        $tutorial->load('childs');
        return new TutorialResource($tutorial);
    }

    public function update(Request $request, Tutorial $tutorial)
    {
        $validated = $request->validate(['title' => 'required|string|max:255']);
        $tutorial->update($validated);
        return new TutorialResource($tutorial);
    }

    public function destroy(Tutorial $tutorial)
    {
        $tutorial->delete();
        return response()->json(['message' => 'Tutorial eliminato con successo']);
    }
}

Ogni metodo rappresenta un verbo HTTP: index per GET, store per POST, update per PUT, destroy per DELETE.
Laravel mappa tutto in automatico tramite Route::apiResource().

Le rotte API

Ora nel file routes/api.php basta una riga per creare l’intera struttura CRUD:

use App\Http\Controllers\Api\TutorialController;

Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('tutorials', TutorialController::class);
});

Tutte le richieste a /api/tutorials saranno protette da token e passeranno per i metodi del controller.

Gestione dell’autenticazione

Laravel Sanctum ti permette di generare token utente per le chiamate API.
Puoi creare un semplice controller per la gestione dei token:

php artisan make:controller Api/AuthController

E dentro scrivere:

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $data = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:6',
        ]);

        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);

        return response()->json(['token' => $user->createToken('api')->plainTextToken]);
    }

    public function login(Request $request)
    {
        $data = $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        $user = User::where('email', $data['email'])->first();

        if (!$user || !Hash::check($data['password'], $user->password)) {
            return response()->json(['message' => 'Credenziali errate'], 401);
        }

        return response()->json(['token' => $user->createToken('api')->plainTextToken]);
    }

    public function logout(Request $request)
    {
        $request->user()->tokens()->delete();
        return response()->json(['message' => 'Logout effettuato']);
    }
}

Le rotte pubbliche saranno:

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);

Dopo il login, il token ricevuto va inviato in ogni richiesta autenticata come Authorization: Bearer <token>.

Validazione e sicurezza

Laravel gestisce la validazione direttamente nel controller con $request->validate(), ma per API più complesse puoi creare FormRequest dedicati. Tutto questo evita input non validi o malevoli.
Sanctum invece protegge gli endpoint sensibili, assicurando che solo utenti autenticati possano creare, aggiornare o cancellare dati.

Risposta JSON e testing

Ogni risposta viene automaticamente serializzata in JSON, con codici di stato HTTP corretti (201 per creazione, 200 per successo, 404 se una risorsa non esiste).
Puoi testare facilmente la tua API con Postman o direttamente via curl:

curl -H "Authorization: Bearer <token>" http://localhost:8000/api/tutorials

Conclusione

Laravel 10 offre tutto quello che serve per costruire API RESTful moderne: un ORM potente con Eloquent, un sistema di autenticazione elegante con Sanctum, validazione integrata, e soprattutto le API Resource, che permettono di restituire JSON puliti e coerenti.
Con pochi file e un po’ di attenzione all’architettura, puoi realizzare un backend sicuro, scalabile e perfettamente integrabile con qualsiasi frontend o app mobile.

Quando arrivi a vedere il tuo JSON pulito, con relazioni nidificate e token funzionanti, una sola cosa ti viene da dire:
Daje.