WordPress Headless กับ Distributed System —
WordPress Headless CMS

WordPress Headless คือการใช้ WordPress เป็น Content Management System ที่ให้ข้อมูลผ่าน API เท่านั้น ไม่ใช้ Theme แสดงผล Frontend สร้างด้วย Framework สมัยใหม่เช่น Next.js, Nuxt.js หรือ Astro ทำให้เว็บเร็วขึ้นมากและ Scale ได้ดี
ในระบบ Distributed กระจาย WordPress ข้าม Regions, Database Replication, CDN, Redis Cache ทำให้ระบบ High Availability และเร็วสำหรับผู้ใช้ทั่วโลก
WordPress Headless Setup
=== WordPress Headless Setup ===
1. ติดตั้ง WordPress + WPGraphQL
docker-compose.yml
version: '3.8'
services:
wordpress:
image: wordpress:6.5-php8.3-apache
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wp
WORDPRESS_DB_PASSWORD: SecurePass123
WORDPRESS_CONFIG_EXTRA: |
define('WP_HOME', 'https://cms.example.com');
define('WP_SITEURL', 'https://cms.example.com');
define('HEADLESS_MODE', true);
define('GRAPHQL_JWT_AUTH_SECRET_KEY', 'your-secret-key');
volumes:
- wp-data:/var/www/html
depends_on:
- mysql
- redis
mysql:
image: mysql:8.0
environment:

MYSQL_DATABASE: wordpress
MYSQL_USER: wp
MYSQL_PASSWORD: SecurePass123
MYSQL_ROOT_PASSWORD: RootPass123
volumes:
- db-data:/var/lib/mysql
command: >
--default-authentication-plugin=mysql_native_password
--innodb-buffer-pool-size=256M
--max-connections=200
redis:
image: redis:7-alpine
command: redis-server --maxmemory 128mb --maxmemory-policy allkeys-lru
volumes:
wp-data:
db-data:
2. ติดตั้ง Plugins
เนื้อหาเกี่ยวข้อง — TTS Coqui Batch Processing Pipeline
wp plugin install wp-graphql --activate
wp plugin install wp-graphql-jwt-authentication --activate
wp plugin install redis-cache --activate
3. Headless Mode (functions.php)
Redirect frontend to API
add_action('template_redirect', function() {
if (!defined('HEADLESS_MODE') || !HEADLESS_MODE) return;
if (is_admin() || wp_doing_ajax() || wp_doing_cron()) return;
แนะนำเพิ่มเติม — แหล่งความรู้ Forex iCafeForex
if (strpos($_SERVER['REQUEST_URI'], '/graphql') !== false) return;
if (strpos($_SERVER['REQUEST_URI'], '/wp-json') !== false) return;
wp_redirect('https://www.example.com', 301);
exit;
});
4. CORS Headers
Allow frontend domain
add_action('init', function() {
header('Access-Control-Allow-Origin: https://www.example.com');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
});
5. ทดสอบ GraphQL
curl -X POST https://cms.example.com/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ posts { nodes { title slug excerpt date } } }"}'
echo "WordPress Headless CMS configured"
echo " REST API: https://cms.example.com/wp-json/wp/v2/"
echo " GraphQL: https://cms.example.com/graphql"
Next.js Frontend สำหรับ Headless WordPress
// === Next.js Frontend สำหรับ Headless WordPress ===
// npx create-next-app@latest frontend --typescript --tailwind
// lib/wordpress.ts — WordPress API Client
const API_URL = process.env.WORDPRESS_GRAPHQL_URL || "https://cms.example.com/graphql";
interface Post {
title: string;
slug: string;
excerpt: string;
date: string;
content: string;
featuredImage?: {
node: { sourceUrl: string; altText: string };
};
categories: { nodes: { name: string; slug: string }[] };
}
async function fetchGraphQL(query: string, variables?: Record<string, any>) {
const res = await fetch(API_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query, variables }),
next: { revalidate: 60 }, // ISR: Revalidate ทุก 60 วินาที
});
if (!res.ok) throw new Error(`GraphQL error: `);
const json = await res.json();
if (json.errors) throw new Error(json.errors[0].message);
return json.data;
}
// ดึง Posts ทั้งหมด
export async function getPosts(first = 20): Promise<Post[]> {
const data = await fetchGraphQL(`
query GetPosts($first: Int!) {
posts(first: $first, where: { status: PUBLISH }) {
nodes {
title
slug
excerpt
date
featuredImage {
node { sourceUrl altText }
}
categories {
nodes { name slug }
}
}
}
}
`, { first });
return data.posts.nodes;
}
// ดึง Post เฉพาะ
export async function getPost(slug: string): Promise<Post> {
const data = await fetchGraphQL(`
query GetPost($slug: ID!) {
post(id: $slug, idType: SLUG) {
title
slug
content
date
excerpt
featuredImage {
node { sourceUrl altText }
}
categories {
nodes { name slug }
}
}
}
`, { slug });
return data.post;
}
// ดึง Slugs สำหรับ Static Generation
export async function getAllSlugs(): Promise<string[]> {
const data = await fetchGraphQL(`
query GetSlugs {
posts(first: 1000, where: { status: PUBLISH }) {
nodes { slug }
}
}
`);
return data.posts.nodes.map((p: { slug: string }) => p.slug);
}
// === app/page.tsx — Homepage ===
// export default async function Home() {
// const posts = await getPosts(12);
// return (
// <main className="max-w-6xl mx-auto px-4 py-8">
// <h1 className="text-4xl font-bold mb-8">Blog</h1>
// <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
// {posts.map((post) => (
// <PostCard key={post.slug} post={post} />
// ))}
// </div>
// </main>
// );
// }
// === app/blog/[slug]/page.tsx — Single Post ===
// export async function generateStaticParams() {
// const slugs = await getAllSlugs();
// return slugs.map((slug) => ({ slug }));
// }
//
// export default async function BlogPost({ params }) {
// const post = await getPost(params.slug);
// return (
// <article className="max-w-3xl mx-auto px-4 py-8">
// <h1 className="text-4xl font-bold">{post.title}</h1>
// <div dangerouslySetInnerHTML={{ __html: post.content }} />
// </article>
// );
// }
console.log("Next.js Headless WordPress Frontend");
console.log(" ISR: Revalidate every 60 seconds");
console.log(" SSG: Pre-render all posts at build time");
Distributed Architecture
=== Distributed WordPress Architecture ===
เนื้อหาเกี่ยวข้อง — อ่านต่อ: Fivetran Connector Career Development IT
1. MySQL Replication (Primary-Replica)
Primary: Write Queries (INSERT, UPDATE, DELETE)
Replica: Read Queries (SELECT) — สำหรับ GraphQL Queries
my.cnf (Primary)
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
gtid-mode = ON
enforce-gtid-consistency = ON
my.cnf (Replica)
[mysqld]
server-id = 2
relay-log = mysql-relay
read-only = ON
แนะนำเพิ่มเติม — คู่มือเทรดจาก SiamCafeBook
gtid-mode = ON
enforce-gtid-consistency = ON
2. Redis Cluster สำหรับ Object Cache
redis-cluster.conf
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
redis-cli --cluster create \
node1:6379 node2:6379 node3:6379 \
node4:6379 node5:6379 node6:6379 \
--cluster-replicas 1
3. S3-compatible Object Storage สำหรับ Media
เนื้อหาเกี่ยวข้อง — บทความที่เกี่ยวข้อง: stable diffusion install
wp-config.php
define('AS3CF_SETTINGS', serialize(array(
'provider' => 'aws',
'access-key-id' => 'YOUR_KEY',
'secret-access-key' => 'YOUR_SECRET',
'bucket' => 'wp-media-bucket',
'region' => 'ap-southeast-1',
'copy-to-s3' => true,
'serve-from-s3' => true,
'remove-local-file' => true,
)));
4. Nginx Load Balancer
upstream wordpress {
least_conn;
server wp-node1:8080 weight=5;
server wp-node2:8080 weight=5;
server wp-node3:8080 weight=3; # Smaller instance
}
server {
listen 443 ssl http2;
server_name cms.example.com;
# GraphQL Endpoint — Cache 60s
location /graphql {
proxy_pass http://wordpress;
proxy_cache wp_cache;
proxy_cache_valid 200 60s;
proxy_cache_key "$request_body";
proxy_cache_methods POST;
เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน chatgpt prompt engineering
add_header X-Cache $upstream_cache_status;
}
# REST API — Cache 60s
location /wp-json/ {
proxy_pass http://wordpress;
proxy_cache wp_cache;
proxy_cache_valid 200 60s;
}
# Admin — No Cache
location /wp-admin {
proxy_pass http://wordpress;
}
}
5. CDN สำหรับ Frontend
Vercel, Cloudflare Pages, Netlify
Frontend Deploy เป็น Static/ISR บน CDN
ผู้ใช้โหลดจาก Edge ใกล้ที่สุด
WordPress API ถูกเรียกตอน Revalidation เท่านั้น
print("Distributed WordPress Architecture:")
print(" WordPress (3 nodes) -> Nginx LB")
print(" MySQL Primary -> 2 Replicas")
print(" Redis Cluster (6 nodes)")
print(" S3 Object Storage for Media")
print(" CDN for Frontend (Next.js ISR)")
print(" GraphQL Cache at Nginx (60s TTL)")
Best Practices
- ISR (Incremental Static Regeneration): ใช้ ISR ใน Next.js Revalidate ทุก 60 วินาที ไม่ต้อง Rebuild ทั้งเว็บ
- GraphQL over REST: ใช้ WPGraphQL ดึงข้อมูลตรงตามต้องการ ลด Over-fetching
- Cache GraphQL: Cache GraphQL Responses ที่ Nginx หรือ CDN ลด Load บน WordPress
- Database Replication: แยก Read/Write ส่ง GraphQL Queries ไป Replica
- Media on S3: เก็บ Media Files บน S3 ส่งผ่าน CDN ไม่ใช้ Disk บน WordPress
- Webhook Revalidation: ใช้ Webhook เมื่อ Publish/Update Post เรียก Revalidation บน Next.js
WordPress Headless คืออะไร
ใช้ WordPress เป็น Backend CMS ไม่ใช้ Theme แสดงผล ใช้ REST API หรือ WPGraphQL ส่งข้อมูลไป Frontend ที่สร้างด้วย Next.js Vue Nuxt แยก Backend กับ Frontend





