Site

HTTP Data

v4

O data define o que a API devolve. O model continua no banco; o data é o contrato JSON. Classe base: MUCRM\engine\http\data. Seus contratos ficam em app/http/data/ com namespace MUCRM\http\data.

💡Por que existe
Sem data, um customer::first() vaza password e colunas internas. Com data você escolhe o JSON: id, name, order_items.

Criar um data

Um arquivo por entidade. Implemente to_array() — tudo snake_case.

<?php

namespace MUCRM\http\data;

use MUCRM\engine\http\data as base_data;

class post_data extends base_data
{
    public function to_array(): array
    {
        return [
            'id'    => $this->id,
            'title' => $this->title,
            'slug'  => $this->slug,
        ];
    }
}

$this->title lê o model original automaticamente.


Responder no handler

use MUCRM\engine\support\request;
use MUCRM\http\data\customer_data;

public function me(request $req)
{
    $customer = $req->user();
    $customer->load('order_items');

    return json([
        'success'  => true,
        'customer' => customer_data::make($customer),
    ]);
}
MétodoUso
::make($model)Um item
::collection($items)Lista
::paginated($paginator)Lista paginada (data + meta)
->to_json()String JSON

Lista e paginação

$posts = post::where('published', true)
    ->order_by('created_at', 'DESC')
    ->limit(20)
    ->get();

return json([
    'success' => true,
    'items'   => post_data::collection($posts),
]);
$items = order_item::where('customer_id', $customer->id)
    ->paginate(12);

return json([
    'success' => true,
    ...order_item_data::paginated($items),
]);

Campos condicionais

return [
    'name'  => $this->name,
    'email' => $this->when($this->show_email, $this->email),
    'admin' => $this->when((int) $this->role === 1, true, false),
];

return array_merge([
    'name' => $this->name,
], $this->merge_when($this->role > 0, [
    'role' => $this->role,
]));
HelperCondição falsa
when()chave fica com null
merge_when()chaves somem

Relações

Relação só entra no JSON se já foi carregada com load() / with().

$customer->load('order_items', 'billing_profile');

class customer_data extends base_data
{
    public function to_array(): array
    {
        return array_merge([
            'id'    => $this->id,
            'name'  => $this->name,
            'email' => $this->email,
        ], $this->merge_relation('order_items', order_item_data::class));
    }
}

// Relação loaded → inclui; senão → omite a chave
'profile' => $this->when_loaded(
    'billing_profile',
    fn ($p) => billing_profile_data::make($p)->to_array()
),
🚨Não faça lazy load no data
Nunca acesse $this->billing_profile cru — use merge_relation() ou when_loaded().

CRUD

public function store(request $req)
{
    $payload = $req->check([
        'title'   => 'required|string|max:120',
        'content' => 'required|string',
    ]);

    $post = post::create([
        ...$payload,
        'customer_id' => $req->user()->id,
        'published'   => true,
    ]);

    return json(['success' => true, 'post' => post_data::make($post)], 201);
}

Envelope JSON: Respostas JSON.


Cheat sheet

post_data::make($post);
post_data::collection($posts);
order_item_data::paginated($paginator);

$this->when($ok, $value);
$this->merge_when($ok, ['extra' => 1]);
$this->merge_relation('tags', tag_data::class);
$this->when_loaded('author', fn ($a) => customer_data::make($a)->to_array());