eduardweb.
WooCommerce & WordPressIntermediar#wordpress#graphql#headless#acf#rest-api

Cum expui CPT și ACF curat în WordPress Headless fără să sufoci payload-ul

De Florin Manea, 13 oct. 2026 · 4 vizualizări · 2 like-uri

Postat acum 3 zile
php
add_action('rest_api_init', function () {
    register_rest_field('proiecte', 'date_specifice', [
        'get_callback' => function ($post) {
            $imagine_id = get_field('imagine_hero', $post['id']);
            
            return [
                'an_lansare' => (int) get_field('an', $post['id']),
                'client'     => sanitize_text_field(get_field('client_nume', $post['id'])),
                'imagine'    => $imagine_id ? [
                    'url' => wp_get_attachment_image_url($imagine_id, 'large'),
                    'alt' => get_post_meta($imagine_id, '_wp_attachment_image_alt', true) ?: '',
                ] : null,
            ];
        },
        'schema' => null,
    ]);
});

La un catalog recent cu vreo 4.000 de produse și povești de brand într-un setup headless, am observat că pagina de listing descărca aproape 6MB de JSON la prima încărcare. Clientul se plângea că pe mobil aplicația de Next.js agăța la parsare, deși baza de date pe serverul de WP rula pe NVMe și răspundea rapid. Problema nu era serverul, ci modul neglijent în care WordPress și ACF scuipau datele în API.

Implicit, tendința multora este să instaleze pluginul clasic „ACF to REST API” și să bifeze show_in_rest peste tot. Rezultatul e o ciorbă de metadate unde fiecare câmp vine la pachet cu clase CSS interne, ID-uri de setări, opțiuni de repeater nefolosite și referințe circulare. La 20 de postări pe pagină, JSON-ul tău devine un monstru.

REST customizat vs WPGraphQL

Aici ai două căi mari, fiecare cu compromisurile ei clare.

Dacă mergi pe WPGraphQL (împreună cu WPGraphQL for ACF), experiența pe frontend este genială. Schema devine puternic tipată, iei strict câmpurile de care are nevoie componenta de React și elimini complet bloat-ul. Am economisit cam 75% din dimensiunea payload-ului doar trecând o pagină complexă pe GraphQL. Însă trade-off-ul e la caching: caching-ul la nivel de CDN (Cloudflare sau Fastly) pe query-uri POST de GraphQL e mult mai migălos de configurat decât un simplu GET /wp-json/wp/v2/proiecte pe care îl ții în cache 10 minute fără bătăi de cap.

Dacă rămâi pe REST API nativ, secretul e să ignori plugin-urile automate de expunere și să-ți declari manual proprietățile prin register_rest_field. Da, scrii 15 linii de PHP în plus per CPT, dar payload-ul rămâne chirurgical de curat.

Cum abordezi expunerea manuală

Când declari Custom Post Type-ul, lași 'show_in_rest' => true, dar nu permiți pluginurilor să injecteze tot blocul de ACF în rădăcină. Prefer să mapez un singur nod meta_custom sau fields unde extrag doar ce consumă efectiv UI-ul.

În callback-ul de citire, nu folosi direct get_fields($post->ID) dacă ai relații adânci sau galerii mari. get_field() individual pe cele 3-4 proprietăți cheie e mai rapid și evită interogările SQL recursive pe tabelele de postmeta. Dacă ai o imagine, returnează direct un obiect mic cu url, alt, width, height, nu tot obiectul de atașament generat de WordPress cu toate cele 12 thumbnail-uri intermediate.

Pe proiectul de care ziceam, doar eliminând metadatele interne de ACF și formatând manual răspunsul de REST am scăzut TTFB-ul cu 40% și am tăiat payload-ul de la 6MB la 320KB pentru aceeași listă de elemente.

Pentru un proiect mediu, voi preferați simplitatea unui endpoint REST customizat sau treceți direct la schema oferită de WPGraphQL?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.