Saltar al contenido principal

Qué son los Support Contracts

Illuminate\Contracts\Support reúne interfaces pequeñas pero importantes que Laravel usa en todas partes. En particular, Arrayable / Jsonable / Htmlable / Responsable son los patrones básicos para integrar de forma natural Value Objects, DTOs y objetos de respuesta en los flujos existentes de Laravel.
Las firmas mostradas aquí se basan en el código fuente oficial (laravel/framework) de Laravel 13.x.

1) Arrayable

Definición de la interfaz

interface Arrayable
{
    public function toArray();
}

Ejemplo de implementación

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,
        ];
    }
}

Ejemplos en el core de Laravel

  • Illuminate\Database\Eloquent\Model implementa Arrayable y ofrece toArray().
  • Illuminate\Http\JsonResponse::setData() detecta Arrayable y serializa con json_encode($data->toArray(), ...).

Uso en el desarrollo de paquetes

  • Puedes unificar el formato de DTOs y Value Objects en controladores, resources y logs.
  • La responsabilidad de la conversión a array queda dentro del propio objeto.

2) Jsonable

Definición de la interfaz

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

Ejemplo de implementación

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);
    }
}

Ejemplos en el core de Laravel

  • Model también implementa Jsonable y ofrece toJson($options = 0).
  • JsonResponse::setData() prioriza Jsonable y usa su toJson().

Uso en el desarrollo de paquetes

  • Puedes fijar estrictamente la estructura JSON en audit logs y webhooks.
  • Explicitas la representación JSON según las necesidades de dominio en vez de delegarla en json_encode().

3) Htmlable

Definición de la interfaz

interface Htmlable
{
    public function toHtml();
}

Ejemplo de implementación

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>";
    }
}

Ejemplos en el core de Laravel

  • Illuminate\Support\HtmlString implementa Htmlable.
  • El helper e() devuelve toHtml() cuando el argumento es Htmlable (no vuelve a escapar).

Uso en el desarrollo de paquetes

  • Aclara la frontera de responsabilidad al pasar fragmentos de HTML seguros dentro de Blade.
  • Aunque uses {!! $obj !!}, es más fácil gestionar la salida con un objeto.
Dentro de una clase que implementa Htmlable, no concatenes datos del usuario directamente: escápalos con e() antes de embutirlos.

4) Responsable

Definición de la interfaz

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

Ejemplo de implementación

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',
        ]);
    }
}

Ejemplos en el core de Laravel

  • Illuminate\Routing\Router::toResponse() detecta primero Responsable e invoca $response->toResponse($request).
  • Illuminate\Http\Resources\Json\JsonResource implementa Responsable, por lo que puedes hacer return UserResource::make($user); directamente desde un controlador.

Uso en el desarrollo de paquetes

  • Delegas la construcción de la respuesta en un objeto en lugar de armar arrays en el controlador.
  • Facilita el diseño «devuelvo el DTO tal cual», separando la representación HTTP de la de dominio.

Guía para elegir la implementación

1

Quieres reutilizar los datos como array

Implementa Arrayable y concentra la lógica de normalización en toArray().
2

Quieres controlar la representación JSON

Implementa Jsonable y explicita el formato de salida en toJson($options).
3

Quieres tratarlo como fragmento HTML

Implementa Htmlable y devuelve el markup en toHtml().
4

Quieres devolver directamente una respuesta HTTP

Implementa Responsable y concentra la responsabilidad en toResponse($request).

Siguientes lecturas

Trait Macroable

Aprende el patrón para extender clases existentes con métodos propios.

Trait Conditionable

Diseño de bifurcaciones condicionales con when() / unless().

Helper tap() / Tappable

Cadenas que devuelven el valor mientras intercalan efectos colaterales.

Trait Dumpable

Técnicas de depuración integrando dump() / dd() en tus objetos.
Última modificación el 13 de julio de 2026