Directus CMS Feature Flag Management — จัดการ
Directus Feature Flag

Directus Headless CMS REST GraphQL API Feature Flag Toggle Canary Release A/B Testing Kill Switch Progressive Rollout Role-based Access Webhooks Flows
| Feature Flag Type | ใช้เมื่อ | ตัวอย่าง |
|---|---|---|
| Release Flag | ปล่อยฟีเจอร์ใหม่ | New checkout flow |
| Experiment Flag | A/B Testing | Button color test |
| Ops Flag | ควบคุมระบบ | Maintenance mode |
| Permission Flag | ควบคุมสิทธิ์ | Premium features |
| Kill Switch | ปิดฟีเจอร์ฉุกเฉิน | Disable payments |
Directus Setup และ Feature Flag Schema
=== Directus Feature Flag Setup ===
Docker Compose
version: '3.8'
services:
directus:
image: directus/directus:latest
ports:
- "8055:8055"
environment:
KEY: "random-key-here"
SECRET: "random-secret-here"
DB_CLIENT: "pg"
DB_HOST: "db"
DB_PORT: "5432"
DB_DATABASE: "directus"
DB_USER: "directus"
DB_PASSWORD: "directus"
ADMIN_EMAIL: "admin@example.com"
ADMIN_PASSWORD: "admin123"
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_DB: directus
POSTGRES_USER: directus
POSTGRES_PASSWORD: directus
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Feature Flag Schema (SQL)
CREATE TABLE feature_flags (
id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
เนื้อหาเกี่ยวข้อง — ดูเพิ่มเติมเรื่อง Rust Axum GreenOps Sustainability
enabled BOOLEAN DEFAULT false,
rollout_percentage INT DEFAULT 0,
target_users JSONB DEFAULT '[]',
target_groups JSONB DEFAULT '[]',
metadata JSONB DEFAULT '{}',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
แนะนำเพิ่มเติม — บทวิเคราะห์จาก XM Signal
);
from dataclasses import dataclass, field
from typing import List, Dict, Optional
@dataclass
class FeatureFlag:
name: str
description: str
enabled: bool
rollout_pct: int
target_groups: List[str]
flag_type: str
created: str
flags = [
FeatureFlag("new_checkout", "New checkout flow with Stripe", True, 25,
["beta_users", "internal"], "Release", "2024-03-01"),
FeatureFlag("dark_mode", "Dark mode UI", True, 100,
["all"], "Release", "2024-02-15"),
FeatureFlag("ai_recommendations", "AI product recommendations", True, 10,
เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน agentic rag คือ — ข้อมูลครบถ้วน 2026
["premium"], "Experiment", "2024-03-10"),
FeatureFlag("maintenance_mode", "Enable maintenance page", False, 0,
["all"], "Ops", "2024-01-01"),
FeatureFlag("payment_gateway_v2", "New payment gateway", True, 50,
["beta_users"], "Release", "2024-03-05"),
FeatureFlag("kill_notifications", "Disable push notifications", False, 0,
["all"], "Kill Switch", "2024-02-20"),
]
print("=== Feature Flags Dashboard ===")
for f in flags:
status = "ON" if f.enabled else "OFF"
groups = ", ".join(f.target_groups)
print(f" [{status}] {f.name} ({f.flag_type})")
print(f" {f.description}")
แนะนำเพิ่มเติม — หนังสือเทรดที่ SiamCafeBook
print(f" Rollout: {f.rollout_pct}% | Groups: {groups}")
API และ SDK Integration
=== Feature Flag API ===
Directus REST API
GET /items/feature_flags
GET /items/feature_flags?filter[name][_eq]=new_checkout
PATCH /items/feature_flags/1 {"enabled": true, "rollout_percentage": 50}
Python SDK
from directus_sdk import DirectusClient
client = DirectusClient("http://localhost:8055", token="YOUR_TOKEN")
# Get all flags
flags = client.get_items("feature_flags")
เนื้อหาเกี่ยวข้อง — ดูเพิ่มเติมเรื่อง Sora AI คืออะไร — ข้อมูลครบถ้วน 2026
# Check flag for user
def is_enabled(flag_name, user_id=None, user_group=None):

flag = client.get_items("feature_flags",
params={"filter[name][_eq]": flag_name})
if not flag:
return False
flag = flag[0]
if not flag["enabled"]:
return False
# Check target groups
if user_group and flag["target_groups"]:
if user_group not in flag["target_groups"] and "all" not in flag["target_groups"]:
return False
# Check rollout percentage
if flag["rollout_percentage"] < 100:
import hashlib
hash_val = int(hashlib.md5(f"{flag_name}:{user_id}".encode()).hexdigest(), 16)
if (hash_val % 100) >= flag["rollout_percentage"]:
return False
return True
JavaScript Client
import { createDirectus, rest, readItems } from '@directus/sdk';
const client = createDirectus('http://localhost:8055').with(rest());
async function getFlag(name) {
const flags = await client.request(
readItems('feature_flags', {
filter: { name: { _eq: name } },
})
);
return flags[0] || null;
}
เนื้อหาเกี่ยวข้อง — ดูเพิ่มเติมเรื่อง React Server Components Compliance Automation
Usage in React
function FeatureGate({ flag, children, fallback }) {
const [enabled, setEnabled] = useState(false);
useEffect(() => {
getFlag(flag).then(f => setEnabled(f?.enabled));
}, [flag]);
return enabled ? children : (fallback || null);
}
import hashlib
def check_rollout(flag_name: str, user_id: str, rollout_pct: int) -> bool:
hash_val = int(hashlib.md5(f"{flag_name}:{user_id}".encode()).hexdigest(), 16)
return (hash_val % 100) < rollout_pct
print("\nRollout Simulation (new_checkout at 25%):")
users = [f"user_{i}" for i in range(20)]
enabled_count = sum(1 for u in users if check_rollout("new_checkout", u, 25))
print(f" {enabled_count}/{len(users)} users enabled ({enabled_count/len(users)*100:.0f}%)")
Flows Automation และ Best Practices
# === Directus Flows for Feature Flags ===
# Flow: Auto-disable flag after date
# Trigger: Schedule (daily)
# Operations:
# 1. Read Items: feature_flags where end_date < today
# 2. Update Items: set enabled = false
# 3. Send Webhook: notify Slack
# Flow: Gradual rollout
# Trigger: Manual
# Operations:
# 1. Read current rollout_percentage
# 2. Increase by 10%
# 3. Wait 1 hour
# 4. Check error rate from monitoring
# 5. If OK: increase again, else rollback to 0%
best_practices = {
"Naming": [
"ใช้ snake_case: new_checkout, dark_mode",
"Prefix ตาม type: release_, exp_, ops_",
"ชื่อบอก context: payment_gateway_v2",
],
"Lifecycle": [
"สร้าง Flag ก่อน Deploy code",
"เปิด Flag ทีละ % (5, 25, 50, 100)",
"Monitor Metrics ทุกขั้น",
"ลบ Flag หลังใช้เสร็จ (Technical Debt)",
],
"Testing": [
"ทดสอบทั้ง ON และ OFF",
"ทดสอบ Default (Flag ไม่มี)",
"ทดสอบ Rollout % ถูกต้อง",
"ทดสอบ Target Groups ถูกกลุ่ม",
],
"Operations": [
"Kill Switch สำหรับทุกฟีเจอร์สำคัญ",
"Audit Log ทุกการเปลี่ยนแปลง Flag",
"Alert เมื่อ Flag เปลี่ยนใน Production",
"Review Flags ทุกเดือน ลบที่ไม่ใช้",
],
}
print("Feature Flag Best Practices:")
for category, tips in best_practices.items():
print(f"\n [{category}]")
for tip in tips:
print(f" - {tip}")
# Comparison with dedicated services
comparison = {
"Directus (DIY)": {"cost": "Free (self-hosted)", "features": "Basic", "setup": "ง่าย"},
"LaunchDarkly": {"cost": "$10/mo+", "features": "Enterprise", "setup": "SDK ครบ"},
"Unleash": {"cost": "Free (OSS)", "features": "Advanced", "setup": "ปานกลาง"},
"Flagsmith": {"cost": "Free (OSS)", "features": "Advanced", "setup": "ปานกลาง"},
}
print(f"\n\nFeature Flag Services:")
for service, info in comparison.items():
print(f" [{service}]")
for k, v in info.items():
print(f" {k}: {v}")
เคล็ดลับ
- Kill Switch: ทุกฟีเจอร์สำคัญต้องมี Kill Switch ปิดได้ทันที
- Cleanup: ลบ Flag ที่ใช้เสร็จแล้ว ไม่อย่างนั้นเป็น Technical Debt
- Gradual: ปล่อยฟีเจอร์ทีละ % ดู Metrics ก่อนเพิ่ม
- Directus: ใช้ Directus เป็น Feature Flag Service เมื่อไม่ต้องการฟีเจอร์ซับซ้อน
- Cache: Cache Flags ฝั่ง Client ลด API Calls ตั้ง TTL 1-5 นาที
การนำความรู้ไปประยุกต์ใช้งานจริง
แหล่งเรียนรู้ที่แนะนำ ได้แก่ Official Documentation ที่อัพเดทล่าสุดเสมอ Online Course จาก Coursera Udemy edX ช่อง YouTube คุณภาพทั้งไทยและอังกฤษ และ Community อย่าง Discord Reddit Stack Overflow ที่ช่วยแลกเปลี่ยนประสบการณ์กับนักพัฒนาทั่วโลก
เปรียบเทียบข้อดีและข้อเสีย
จากตารางเปรียบเทียบจะเห็นว่าข้อดีมีมากกว่าข้อเสียอย่างชัดเจน โดยเฉพาะในแง่ของประสิทธิภาพและความสามารถในการ Scale สำหรับข้อเสียส่วนใหญ่สามารถแก้ไขได้ด้วยการเรียนรู้อย่างเป็นระบบและวางแผนทรัพยากรให้เหมาะสม
Directus คืออะไร
Open Source Headless CMS REST GraphQL API Database Admin UI RBAC Webhooks Flows PostgreSQL MySQL Self-hosted Cloud
Feature Flag คืออะไร
เปิด/ปิดฟีเจอร์ไม่ต้อง Deploy Canary Release A/B Testing Kill Switch ลดความเสี่ยง Config แทน Code
Directus ใช้เป็น Feature Flag Service ได้อย่างไร
สร้าง Collection feature_flags API Endpoint Client ดึง Flags Flows Automation Roles สิทธิ์ Webhooks แจ้งเตือน
Feature Flag กับ Feature Toggle ต่างกันไหม
คำเดียวกัน Toggle Boolean เปิด/ปิด Flag Conditions ซับซ้อนกว่า ทางปฏิบัติใช้แทนกัน LaunchDarkly Unleash Flagsmith
สรุป
Directus Headless CMS Feature Flag Toggle REST GraphQL API Canary Release A/B Testing Kill Switch Progressive Rollout Flows Automation Best Practices Lifecycle Cleanup Cache




