← Laravel: pedidos, dados e decisões de aplicação
08 / 10 · 65 MIN

Blade, saída e recursos de API

Definir representações adequadas ao contexto HTML, JavaScript e API. Controlar campos, cálculo condicional, relações carregadas e envelopes de paginação, distinguindo apresentação de autorização.

Texto escapado e saída raw

Para apresentar um comentário como texto num elemento HTML, usa o escaping normal de {{ $comment }}. A forma {!! $comment !!}

emite o valor sem esse escaping; trim ou a origem numa base de dados não tornam conteúdo de utilizador seguro. Define o contrato antes de escolher a saída: texto comum não precisa de interpretar marcação fornecida pelo autor. O escaping é dependente do contexto e não é uma autorização para publicar qualquer dado; campos privados continuam a exigir uma decisão de acesso.

Dados e valores por omissão dos componentes

Num componente com message declarado, message="$notice" passa uma string literal, enquanto :message="$notice" avalia a variável PHP. Observa também os atributos adicionais: merge(["type"=>"button"]) fornece um valor por omissão, mas type="submit" na chamada substitui-o.

O comportamento de class, que combina valores, não deve ser generalizado a type. Ao rever um botão que submete um formulário sem intenção, começa pela chamada efetiva e pelo atributo resultante, em vez de assumir que o valor por omissão era obrigatório.

Método e token são campos distintos

Um formulário HTML POST pode dirigir-se a uma rota PATCH através de @method("PATCH"), que cria _method. @csrf fornece o campo de token usado no fluxo de proteção correspondente. Uma diretiva não substitui a outra: método identifica o contrato da rota, token participa na proteção do pedido.

Mantém também validação e autorização no servidor. Ocultar o formulário com @can melhora a interface para quem não tem permissão, mas não impede um pedido construído diretamente para o mesmo endpoint.

Dados numa expressão JavaScript

Quando uma vista recebe um array para inicializar JavaScript, evita construir aspas e separadores manualmente. Js::from($settings) prepara uma representação escapada para inclusão no HTML e produz a expressão JavaScript que reconstrói o valor.

A documentação recomenda fornecer uma variável existente, em vez de uma expressão complexa no template. Não confundas este contexto de script com o corpo JSON de uma API nem com saída raw de HTML. O consumidor e o local de inclusão determinam o contrato de serialização necessário.

Projetar campos e adiar cálculo condicional

toArray de um JsonResource define a representação dos dados; devolver apenas id e display_name é uma escolha explícita de campos. when remove uma chave quando a condição não passa, mas PHP avalia argumentos antes da chamada: when(false, buildSummary()) ainda chama buildSummary.

Passa uma closure quando o cálculo só deve ocorrer com permissão. A omissão final e a execução anterior são evidências distintas. A condição deve resultar da regra de acesso adequada, e o endpoint continua responsável por autorizar o recurso base.

Relações ausentes, coleções vazias e contagens

whenLoaded recebe o nome da relação para evitar lê-la e carregá-la desnecessariamente. Se não foi carregada, a chave é omitida no resource normal; se foi carregada e não tem elementos, pode ser uma coleção vazia. Estes estados não são equivalentes para o consumidor. whenCounted aplica a distinção aos agregados: tickets_count carregado com zero é uma contagem conhecida e pode ser incluído, enquanto o agregado ausente é omitido.

Nem helper carrega automaticamente todos os modelos para demonstrar ausência.

Paginação faz parte da representação

Uma coleção paginada devolvida pelo mecanismo normal de resources mantém o envelope data, links e meta, mesmo quando foi chamado withoutWrapping. Um cliente preparado para um array na raiz pode falhar apesar de os modelos estarem corretos. Documenta a forma e os estados da resposta, incluindo navegação entre páginas, em vez de depender apenas da configuração global de wrapping.

Qualquer transformação personalizada deve ser acordada e observada nos consumidores; não decorre de carregar mais relações ou alterar a consulta de dados.

{{-- Blade fragments for reading; surrounding application omitted. --}}
<p>{{ $comment }}</p>
<x-alert :message="$notice" />
<form method="POST" action="{{ route('invoices.update', $invoice) }}">
    @csrf
    @method('PATCH')
    {{-- Authorized input fields would be defined here. --}}
</form>
<script>
    const pageSettings = {{ Js::from($settings) }};
</script>

<?php
// Separate JsonResource::toArray excerpt; route already authorized the model.
return [
    'id' => $this->id,
    'tickets' => TicketResource::collection($this->whenLoaded('tickets')),
    'tickets_count' => $this->whenCounted('tickets'),
    'internal_summary' => $this->when(
        $request->user()->can('viewInternal', $this->resource),
        fn () => $this->buildInternalSummary()
    ),
];
NA PRÁTICA

Os fragmentos Blade mostram texto escapado, uma variável passada ao componente, método PATCH sobre POST e dados preparados para JavaScript. O fragmento PHP pertence separadamente a um JsonResource: inclui relações e contagens já carregadas e adia o resumo interno até passar a permissão.

Pressupõe utilizador autenticado, policy, método do resumo, resource de tickets e contexto da vista definidos pela aplicação. Não é um ficheiro completo nem uma tarefa de execução.

Armadilhas comuns

Usar saída raw para comentários de texto; confundir atributo literal e expressão PHP; tratar type=button em merge como obrigatório; esperar que when desfaça avaliação de argumentos; interpretar relação não carregada como vazia; esperar que withoutWrapping elimine o envelope paginado.

Tópicos relacionados: Validação e contratos dos pedidos · Eloquent, relações e custo das consultas · Autenticação, autorização e sessões

Leva esta ideia contigo

A representação é um contrato explícito de campos, contexto e condições. Escolhe escaping e serialização adequados, adia cálculos com closures quando necessário e documenta estados de ausência. A vista e o resource complementam a autorização do endpoint; não a substituem.

Criar conta

Referência: Resource response projection · Laravel 13.x; PHP 8.3+