Vai al contenuto principale

Cosa sono i Support Contracts

Illuminate\Contracts\Support raccoglie interfacce piccole ma importanti, usate in tutto Laravel.
In particolare Arrayable / Jsonable / Htmlable / Responsable sono i pattern di base per far integrare naturalmente Value Object, DTO e response object nel flusso esistente di Laravel.
Le firme mostrate qui fanno riferimento al codice sorgente ufficiale di Laravel 13.x (laravel/framework).

1) Arrayable

Definizione dell’interfaccia

interface Arrayable
{
    public function toArray();
}

Esempio di implementazione

use Illuminate\Contracts\Support\Arrayable;

final class Money implements Arrayable
{
    public function __construct(
        public readonly int $amount,
        public readonly string $currency,
    ) {}

    public function toArray(): array
    {
        return [
            'amount' => $this->amount,
            'currency' => $this->currency,
        ];
    }
}

Utilizzo nel core di Laravel

  • Illuminate\Database\Eloquent\Model implementa Arrayable e fornisce toArray()
  • Illuminate\Http\JsonResponse::setData(), se rileva un Arrayable, serializza con json_encode($data->toArray(), ...)

Aspetti utili nello sviluppo di pacchetti

  • Puoi uniformare il formato di DTO e Value Object in controller, resource e log
  • Concentri sull’oggetto stesso la responsabilità della conversione in array

2) Jsonable

Definizione dell’interfaccia

interface Jsonable
{
    public function toJson($options = 0);
}

Esempio di implementazione

use Illuminate\Contracts\Support\Jsonable;

final class ApiPayload implements Jsonable
{
    public function __construct(
        private array $data,
    ) {}

    public function toJson($options = 0): string
    {
        return json_encode([
            'data' => $this->data,
            'generated_at' => now()->toIso8601String(),
        ], $options | JSON_THROW_ON_ERROR);
    }
}

Utilizzo nel core di Laravel

  • Model implementa anche Jsonable e fornisce toJson($options = 0)
  • JsonResponse::setData() privilegia il controllo di Jsonable e usa toJson()

Aspetti utili nello sviluppo di pacchetti

  • Puoi fissare in modo rigoroso la struttura JSON per audit log e invii webhook
  • Puoi esplicitare la rappresentazione JSON che serve al dominio, senza affidarti a json_encode()

3) Htmlable

Definizione dell’interfaccia

interface Htmlable
{
    public function toHtml();
}

Esempio di implementazione

use Illuminate\Contracts\Support\Htmlable;

final class BadgeHtml implements Htmlable
{
    public function __construct(
        private string $label,
    ) {}

    public function toHtml(): string
    {
        $escaped = e($this->label);

        return "<span class=\"badge\">{$escaped}</span>";
    }
}

Utilizzo nel core di Laravel

  • Illuminate\Support\HtmlString implementa Htmlable
  • L’helper e(), se l’argomento è Htmlable, restituisce il risultato di toHtml() (senza rieseguire l’escape)

Aspetti utili nello sviluppo di pacchetti

  • Chiarisci il confine di responsabilità quando passi frammenti HTML in modo sicuro dentro Blade
  • Anche negli scenari con {!! $obj !!} è più semplice gestire l’output come oggetto
All’interno di una classe che implementa Htmlable, non concatenare direttamente input dell’utente: applica e() ai valori prima di incorporarli.

4) Responsable

Definizione dell’interfaccia

interface Responsable
{
    public function toResponse($request);
}

Esempio di implementazione

use Illuminate\Contracts\Support\Responsable;

final class ExportCsvResponse implements Responsable
{
    public function __construct(
        private array $rows,
        private string $filename = 'export.csv',
    ) {}

    /**
     * @param \Illuminate\Http\Request $request
     */
    public function toResponse($request)
    {
        return response()->streamDownload(function () {
            $stream = fopen('php://output', 'w');

            foreach ($this->rows as $row) {
                fputcsv($stream, $row);
            }

            fclose($stream);
        }, $this->filename, [
            'Content-Type' => 'text/csv',
        ]);
    }
}

Utilizzo nel core di Laravel

  • Illuminate\Routing\Router::toResponse() verifica per prima cosa Responsable e chiama $response->toResponse($request)
  • Illuminate\Http\Resources\Json\JsonResource implementa Responsable, quindi puoi fare direttamente return UserResource::make($user); da un controller

Aspetti utili nello sviluppo di pacchetti

  • Nel controller eviti di comporre array e deleghi la generazione della risposta a un oggetto
  • Facilita un design in cui “restituisci direttamente un DTO”, separando meglio la rappresentazione HTTP da quella di dominio

Guida alla scelta

1

Vuoi convertire i dati in array e riutilizzarli

Implementa Arrayable e centralizza in toArray() la logica di normalizzazione.
2

Vuoi controllare la rappresentazione JSON

Implementa Jsonable ed esplicita il formato di output in toJson($options).
3

Vuoi trattarlo come frammento HTML

Implementa Htmlable e restituisci la stringa da renderizzare in toHtml().
4

Vuoi restituire direttamente una risposta HTTP

Implementa Responsable e concentra la logica in toResponse($request).

Pagine da leggere successivamente

Trait Macroable

Impara il pattern di estensione per aggiungere metodi personalizzati a classi esistenti.

Trait Conditionable

Impara a progettare l’inserimento di rami condizionali con when() / unless().

Helper tap() / Tappable

Impara il design di catene che intercalano side effect restituendo comunque il valore.

Trait Dumpable

Impara la tecnica di debug che integra dump() / dd() negli oggetti.
Ultima modifica il 13 luglio 2026