WordPress kaip headless CMS su REST API

Kodėl apskritai kalbame apie headless architektūrą?

Prieš keletą metų mintis naudoti WordPress kaip headless CMS atrodė keistokai – tarsi bandytum važiuoti automobiliu atbulomis tik todėl, kad taip įdomiau. Bet dabar situacija pasikeitė kardinaliai. Frontendo frameworkai kaip React, Vue ar Next.js tapo tokia kasdienybe, kad tradicinis monolitinis WordPress su savo temomis ir PHP šablonais daugeliui kūrėjų pradeda atrodyti kaip dinozauras.

Headless CMS koncepcija paprasta – atskiri backend’ą (turinio valdymą) nuo frontend’o (turinio atvaizdavimo). WordPress tampa tiesiog duomenų šaltiniu, o kaip tuos duomenis pateiksi vartotojui – tavo reikalas. Gali būti React aplikacija, mobili programėlė, IoT įrenginys ar net keli skirtingi frontendai vienu metu.

Kas įdomiausia – WordPress jau seniai turi įmontuotą REST API. Nuo 4.7 versijos tai standartinė funkcionalybė, kurią galima naudoti iškart po instaliavimo. Nereikia jokių papildomų pluginų ar sudėtingų konfigūracijų. Tiesiog įjungi WordPress, ir tuoj pat gauni visiškai funkcionalų API endpointą.

REST API galimybės ir ką gauni iš dėžės

WordPress REST API yra tikrai solidus dalykas. Pagal nutylėjimą gauni prieigą prie visų pagrindinių turinio tipų – įrašų (posts), puslapių (pages), komentarų, taksonomijų, vartotojų ir net medijos failų. Bazinis endpoint’as yra /wp-json/wp/v2/, ir per jį gali pasiekti praktiškai viską.

Pavyzdžiui, norint gauti paskutinius 10 įrašų, tiesiog kreipiesi į:
https://tavo-svetaine.lt/wp-json/wp/v2/posts?per_page=10

Atsakymas bus JSON formatu su visais įrašo duomenimis – pavadinimu, turiniu, ištrauka, autorium, kategorijomis, žymomis, paveikslėliu ir dar krūva metaduomenų. API palaiko filtravimą, rūšiavimą, paiešką ir puslapiavimą. Galima filtruoti pagal kategoriją, autorių, datą, statusą ir kitus parametrus.

Kas tikrai patogu – API automatiškai grąžina ir papildomą informaciją apie užklausą. Response headeriai turi X-WP-Total (bendras įrašų skaičius) ir X-WP-TotalPages (puslapių skaičius), todėl pagination’ą įgyvendinti labai paprasta.

Autentifikacija irgi išspręsta keliais būdais. Paprasčiausiems atvejams užtenka cookie autentifikacijos, kuri veikia automatiškai, jei esi prisijungęs prie WordPress admin. Rimtesnėms aplikacijoms yra JWT (JSON Web Tokens) arba OAuth palaikymas per papildomus pluginus. Application passwords funkcionalumas, pridėtas WordPress 5.6 versijoje, leidžia generuoti specialius slaptažodžius API prieigai be pagrindinių kredencialų atskleidimo.

Custom post types ir kaip juos eksponuoti per API

Tikroji WordPress jėga slypi custom post types. Jei kuri bet kokį rimtesnį projektą, greičiausiai naudosi pasirinktinius turinio tipus – produktus, portfolio darbus, renginius, komandos narius ar ką nors kita. Gera žinia – juos eksponuoti per REST API yra trivialiai paprasta.

Kai registruoji custom post type, tiesiog pridedi 'show_in_rest' => true parametrą:


register_post_type('produktas', [
'public' => true,
'show_in_rest' => true,
'rest_base' => 'produktai',
'rest_controller_class' => 'WP_REST_Posts_Controller',
]);

Ir viskas – tavo produktai dabar prieinami per /wp-json/wp/v2/produktai. Parametras rest_base leidžia kontroliuoti, kaip atrodys endpoint’o URL, o rest_controller_class nusako, kokia logika bus naudojama duomenų apdorojimui.

Tas pats principas veikia ir su custom taxonomies. Jei turi savo kategorijų sistemą ar žymas, pridedi 'show_in_rest' => true, ir jos tampa prieinamos per API. Tai reiškia, kad gali filtruoti įrašus pagal savo taksonomijas taip pat lengvai kaip pagal standartinius WordPress kategorijas.

Custom fields ir ACF integracija

Čia prasideda tikrasis smagumas. Beveik kiekvienas WordPress projektas naudoja custom fields – papildomus laukus, kurie praturtina standartinį turinį. Populiariausias įrankis tam – Advanced Custom Fields (ACF) pluginas, kuris tapo faktiškai industrijos standartu.

ACF turi puikų REST API palaikymą. Nuo 5.x versijos galima įjungti custom fields eksponavimą per API tiesiog pažymint checkbox’ą field group nustatymuose. Kai tai padarai, visi tie laukai atsiranda API response’e po acf raktu.

Tarkime, turi produkto custom post type su ACF laukais – kaina, aprašymas, techninės specifikacijos. API atsakymas atrodys maždaug taip:


{
"id": 123,
"title": {"rendered": "Super produktas"},
"acf": {
"kaina": "99.99",
"aprasymas": "Detalus aprašymas...",
"specifikacijos": {
"svoris": "1.5kg",
"matmenys": "30x20x10cm"
}
}
}

Jei naudoji kitą custom fields sprendimą arba tiesiog WordPress natyvius meta fields, gali juos eksponuoti per register_meta() funkciją su 'show_in_rest' => true parametru. Tai suteikia pilną kontrolę, kokius duomenis nori atskleisti per API.

Saugumo aspektai ir kas gali nepavykti

Čia reikia būti atsargiems. Pagal nutylėjimą WordPress REST API yra gana atviras – bet kas gali skaityti publikuotą turinį be autentifikacijos. Tai normalu ir dažniausiai norima, bet kartais gali būti per daug.

Pirmas dalykas – API atskleidžia informaciją apie vartotojus. Endpoint’as /wp-json/wp/v2/users grąžina visų svetainės vartotojų sąrašą su jų username’ais. Tai potenciali saugumo spraga, ypač jei naudoji username’us prisijungimui. Sprendimas paprastas – išjungti users endpoint’ą neautentifikuotiems vartotojams:


add_filter('rest_endpoints', function($endpoints) {
if (!is_user_logged_in()) {
unset($endpoints['/wp/v2/users']);
unset($endpoints['/wp/v2/users/(?P[\d]+)']);
}
return $endpoints;
});

Antra problema – rate limiting. WordPress REST API pagal nutylėjimą neturi jokių apribojimų, kiek užklausų gali padaryti. Tai reiškia, kad kažkas gali lengvai „užspaminti” tavo serverį. Yra pluginų, kurie sprendžia šią problemą (pvz., WP REST API Controller), arba gali implementuoti savo rate limiting logiką.

Trečias aspektas – CORS (Cross-Origin Resource Sharing). Jei tavo frontend’as yra kitame domene nei WordPress, naršyklė blokuos API užklausas. Reikia pridėti CORS headerius:


add_action('rest_api_init', function() {
remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
add_filter('rest_pre_serve_request', function($value) {
header('Access-Control-Allow-Origin: https://tavo-frontend.lt');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
header('Access-Control-Allow-Credentials: true');
return $value;
});
}, 15);

Performance optimizacija ir caching strategijos

WordPress nėra greičiausias dalykas pasaulyje, o kai naudoji jį kaip headless CMS, performance tampa dar svarbesnis. Kiekviena API užklausa reiškia PHP procesą, duomenų bazės queries ir visą WordPress bootstrap procesą.

Pirmasis žingsnis – įsitikinti, kad naudoji normalų hosting’ą su PHP 8.x ir OPcache. Tai skamba savaime suprantama, bet nustebsi, kiek projektų vis dar veikia ant PHP 7.2 ar net senesnių versijų. PHP 8.x duoda realų performance boost’ą.

Antra – object caching. WordPress turi įmontuotą object cache sistemą, bet pagal nutylėjimą ji veikia tik vieno request’o metu. Reikia persistent object cache – Redis arba Memcached. Su Redis ir tinkamu caching pluginu (pvz., Redis Object Cache) API response laikas gali sumažėti 3-5 kartus.

Trečia – HTTP caching. REST API response’ai turėtų turėti tinkamus cache headerius. Galima naudoti CDN kaip Cloudflare ar Fastly, kurie cache’ins API atsakymus. Arba implementuoti serverio lygio cache’inimą su Nginx ar Varnish.

Ketvirta – optimizuoti pačias užklausas. Jei nereikia viso įrašo turinio, naudok _fields parametrą, kad gautum tik tai, ko reikia:

/wp-json/wp/v2/posts?_fields=id,title,excerpt,featured_media

Tai gerokai sumažina response dydį ir duomenų bazės apkrovą. Taip pat verta pagalvoti apie duomenų bazės indeksus, ypač jei darai sudėtingas užklausas su meta queries ar taksonomijų filtravimą.

Praktiniai patarimai darbui su Next.js ir React

Jei kuri frontend’ą su React ar Next.js (o greičiausiai taip ir yra), yra keletas dalykų, kurie labai palengvina gyvenimą. Pirma – naudok kokią nors data fetching biblioteką. SWR arba React Query yra puikūs pasirinkimai, nes jie automatiškai tvarko cache’inimą, revalidation’ą ir loading states.

Su Next.js galima išnaudoti Static Site Generation (SSG) arba Incremental Static Regeneration (ISR). Tai reiškia, kad puslapiai generuojami build metu arba pirmojo request’o metu, o paskui cache’inami. Rezultatas – bliksiškai greitas website’as, nors backend’as ir būtų lėtokas WordPress.

Štai paprastas pavyzdys, kaip fetch’inti WordPress įrašus Next.js su ISR:


export async function getStaticProps() {
const res = await fetch('https://tavo-wp.lt/wp-json/wp/v2/posts');
const posts = await res.json();

return {
props: { posts },
revalidate: 60 // Regeneruoti kas 60 sekundžių
};
}

Dėl images – WordPress media library turi visas reikalingas image sizes ir meta informaciją. API grąžina media_details objektą su visais available sizes. Galima naudoti Next.js Image komponentą su WordPress sugeneruotais images, arba implementuoti custom image optimization su Cloudinary ar imgix.

Dar vienas patarimas – naudok TypeScript ir sugeneruok types iš WordPress schema. Yra įrankių kaip openapi-typescript, kurie gali sugeneruoti TypeScript interfaces iš REST API schema endpoint’o (/wp-json). Tai išgelbės nuo daugelio klaidų ir padarys development’ą daug malonesnį.

Kai WordPress REST API nepakanka ir ką daryti toliau

Kartais REST API tiesiog nepakanka. Jei reikia labai sudėtingų užklausų, daug related duomenų arba tiesiog norisi modernesnio API stiliaus, verta pažvelgti į GraphQL. WPGraphQL pluginas yra nuostabus sprendimas, kuris transformuoja WordPress į pilnavertį GraphQL serverį.

GraphQL privalumas – gauni tiksliai tuos duomenis, kurių reikia, viena užklausa. Jei reikia įrašo su autoriaus informacija, featured image, kategorijomis ir related posts, REST API reikėtų padaryti kelis request’us. Su GraphQL – vieną.

Kitas scenarijus – real-time funkcionalumas. REST API yra request-response modelis, todėl real-time updates reikalauja polling’o arba webhook’ų. Jei kuri aplikaciją, kur reikia live updates (pvz., komentarų sistemą ar collaborative editing), gali reikėti papildomų sprendimų kaip WebSockets ar Server-Sent Events.

Taip pat verta pagalvoti apie content preview funkcionalumą. Kai redaktoriai kuria turinį WordPress admin’e, jie nori matyti, kaip jis atrodys frontend’e prieš publikuojant. Su headless setup’u tai nėra automatiškai. Reikia implementuoti preview mode – Next.js turi tam puikų palaikymą su Preview Mode API, bet reikia papildomo kodo WordPress pusėje.

Dėl deployment’o – headless WordPress setup’as dažniausiai reiškia du atskirus serverius: vieną WordPress backend’ui, kitą frontend’ui. Tai suteikia lankstumą, bet ir prideda kompleksiškumo. Frontend’ą gali host’inti Vercel, Netlify ar panašiose platformose, o WordPress – specializuotame WP hosting’e kaip Kinsta ar WP Engine.

Galiausiai, jei projektas auga, gali prireikti content delivery optimizacijos. Webhook’ai, kurie trigger’ina frontend rebuild’ą kai turinys pasikeičia WordPress’e. Build cache’inimas, kad rebuild’ai būtų greitesni. Partial builds, kad nereikėtų rebuild’inti viso site’o kiekvieną kartą. Visa tai įmanoma, bet reikalauja planavimo ir papildomo darbo.

Headless WordPress su REST API nėra silver bullet, bet tai tikrai galingas įrankis tinkamose situacijose. Gauni patikimą, gerai pažįstamą turinio valdymo sistemą su puikia admin sąsaja, kurią redaktoriai jau moka naudoti. Tuo pačiu išlaisvi frontend’ą naudoti modernius frameworkus ir architektūras. Jei projektas to reikalauja – verta bandyti, tik būk pasirengęs papildomam kompleksiškumui ir infrastruktūros valdymui.

Parašykite komentarą

El. pašto adresas nebus skelbiamas. Būtini laukeliai pažymėti *