سال‌ها با وردپرس کار می‌کردم و فکر می‌کردم این سیستم فقط برای ساخت وب‌سایت است. تا روزی که یک مشتری درخواست کرد اپلیکیشن موبایلی سفارش‌ها را به‌طور زنده نشان دهد و از همان اپلیکیشن، وضعیت سفارش را تغییر دهد. اولین فکرم این بود که «باید یک API اختصاصی بسازیم». ولی وقتی به مستندات وردپرس نگاه کردم، متوجه شدم که این کار از سال ۲۰۱۵ به‌صورت بومی در هسته وجود دارد — با نام REST API (Representational State Transfer Application Programming Interface). این مقاله، همان مسیری است که از آن پروژه تا امروز بارها پیموده‌ام؛ از شناخت endpointها تا امنیت، احراز هویت و توسعه‌های سفارشی.

REST API در وردپرس دقیقاً چیست؟

REST API یک رابط برنامه‌نویسی است که بر پایهٔ معماری REST ساخته شده. در این معماری، هر منبع (post، page، user، comment یا هر چیز دیگر) با یک آدرس مشخص در دسترس قرار می‌گیرد و عملیات‌ها با کدهای استاندارد HTTP (HyperText Transfer Protocol — پروتکل انتقال ابرمتن) اجرا می‌شوند: GET برای خواندن، POST برای ایجاد، PUT یا PATCH برای به‌روزرسانی، و DELETE برای حذف. از نسخهٔ ۴٫۷ وردپرس، این قابلیت به‌صورت پیش‌فرض فعال است و آدرس پایهٔ آن با الگوی زیر قابل دسترسی است:

https://example.com/wp-json/wp/v2/

اگر مفهوم کلی API برایتان تازه است، مقالهٔ API چیست و چه کاربردی دارد؟ تصویر درستی می‌دهد. نکتهٔ مهمی که در پروژه‌ها زیاد دیدم: خیلی از توسعه‌دهنده‌ها تصور می‌کنند REST API یک افزونهٔ جداگانه است و سراغ نصب افزونه‌های غیرضروری می‌روند؛ درحالی‌که این قابلیت در هسته وردپرس است.

REST API وردپرس، در واقع همان وردپرس است که به شما اجازه می‌دهد از بیرون با آن حرف بزنید — نه یک افزونه اضافه.

چرا REST API برای پروژه‌های مدرن حیاتی است؟

سه سناریوی مشخص که در تجربهٔ کاری من بدون REST API به‌سختی حل می‌شوند:

  • اپلیکیشن موبایل روی وردپرس: فرض کنید محتوای سایت را می‌خواهید در یک اپ بومی نمایش دهید. با REST API، همان محتوا از دیتابیس وردپرس خوانده می‌شود و به‌صورت JSON (JavaScript Object Notation — قالب متنی برای تبادل داده) به اپ تحویل داده می‌شود.
  • پنل ادمین اختصاصی: برای تیم‌هایی که با پیشخوان وردپرس راحت نیستند، می‌توانید یک داشبورد سفارشی بسازید که از طریق REST API به داده‌ها دسترسی دارد.
  • یکپارچه‌سازی با سرویس‌های خارجی: مثلاً همگام‌سازی محصولات ووکامرس با یک سیستم انبارداری بیرونی، یا اتصال به یک CRM (Customer Relationship Management — مدیریت ارتباط با مشتری).

در دنیای معماری نرم‌افزار، این الگو Headless CMS نامیده می‌شود: وردپرس به‌عنوان مغز و مخزن محتوا، و فرانت‌اند جدا (React، Vue یا اپ موبایل) به‌عنوان مصرف‌کنندهٔ REST API. مسیر فریم‌ورک‌های مصرف‌کننده را در بهترین فریم‌ورک‌های فرانت‌اند کدامند؟ تحلیل کرده‌ام.

کاوش endpointهای پیش‌فرض وردپرس

ساده‌ترین راه برای دیدن فهرست کامل endpointها، باز کردن آدرس زیر در مرورگر است:

https://example.com/wp-json/

خروجی، یک JSON بزرگ با فهرست تمام مسیرهای موجود است. برای یک وردپرس تازهٔ بدون افزونه، endpointهای زیر را خواهید دید:

  • /wp/v2/posts — نوشته‌ها
  • /wp/v2/pages — برگه‌ها
  • /wp/v2/categories — دسته‌بندی‌ها
  • /wp/v2/media — رسانه‌ها
  • /wp/v2/users — کاربران (با محدودیت دسترسی)
  • /wp/v2/comments — دیدگاه‌ها

اگر ووکامرس نصب باشد، آدرس /wp-json/wc/v3/ هم به فهرست اضافه می‌شود. شناخت این مسیرها، اولین قدم عملی است. برای درک دقیق‌تر ساختار داخلی این endpointها در وردپرس، مطالعهٔ ساختار هسته وردپرس چگونه کار می‌کند مفید است.

خواندن داده با درخواست GET

یک درخواست سادهٔ خواندن، به این شکل است:

curl https://example.com/wp-json/wp/v2/posts?per_page=5

این درخواست، پنج نوشتهٔ اخیر را به‌صورت JSON برمی‌گرداند. پارامترهای پرکاربرد در endpoint نوشته‌ها:

  • per_page — تعداد آیتم‌ها در هر صفحه (حداکثر ۱۰۰).
  • page — شمارهٔ صفحه.
  • search — جست‌وجو در عنوان و محتوا.
  • orderby و order — ترتیب.
  • _fields — انتخاب فقط فیلدهای موردنیاز (برای کاهش حجم پاسخ).

استفاده از _fields یک ترفند مهم در عملکرد است. مثلاً به‌جای دریافت پاسخ کامل، می‌توانید بنویسید:

curl "https://example.com/wp-json/wp/v2/posts?_fields=id,title,link"

این کار حجم پاسخ را گاهی بیش از نود درصد کاهش می‌دهد — مخصوصاً برای اپلیکیشن‌های موبایل که مصرف داده مهم است.

نوشتن داده با POST، PUT و DELETE

برای ایجاد یک نوشتهٔ جدید:

curl -X POST https://example.com/wp-json/wp/v2/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"عنوان تست","content":"محتوای تست","status":"draft"}'

نکتهٔ مهم: بدون احراز هویت، این درخواست رد می‌شود. برای به‌روزرسانی از PUT و برای حذف از DELETE استفاده می‌شود. یک قاعدهٔ عملی: قبل از هر درخواست نوشتن، همیشه یک بکاپ دیتابیس بگیرید — به‌خصوص وقتی endpoint سفارشی نوشتید و از رفتارش مطمئن نیستید. روش بکاپ را در چگونه از سایت وردپرسی بکاپ بگیریم آورده‌ام.

احراز هویت: سه روش رایج و کاربردشان

رایج‌ترین راه‌های احراز هویت در REST API وردپرس:

  1. Cookie Authentication: همان سشن پیشخوان وردپرس. فقط از داخل دامنهٔ خودِ سایت کار می‌کند. برای اپ‌های بیرونی مناسب نیست.
  2. Application Passwords: از وردپرس ۵٫۶ به‌صورت پیش‌فرض در هسته قرار گرفته. برای هر اپلیکیشن یا سرویس بیرونی، یک رمز اختصاصی ساخته می‌شود. ساده‌ترین و امن‌ترین گزینه برای ۹۰٪ موارد.
  3. JWT (JSON Web Token): یک توکن امضاشده که پس از ورود معتبر صادر می‌شود و در هر درخواست فرستاده می‌شود. برای پروژه‌های بزرگ و معماری microservice مناسب است ولی نیاز به نصب افزونه دارد.

مقایسهٔ تفصیلی این سه و معایب هرکدام در JWT چیست و چه کاربردی در احراز هویت دارد؟ و احراز هویت در REST API آمده. توصیهٔ شخصی من: برای شروع Application Passwords؛ برای معماری‌های پیچیده، JWT.

ساخت endpoint سفارشی برای افزونه‌های خودتان

وقتی داده‌ای دارید که در endpointهای پیش‌فرض نیست (مثلاً یک متای سفارشی یا یک جدول اختصاصی)، باید endpoint خودتان را بسازید. الگوی استاندارد با هوک rest_api_init انجام می‌شود:

add_action( 'rest_api_init', function () {
    register_rest_route( 'my-plugin/v1', '/orders', array(
        'methods'  => 'GET',
        'callback' => 'my_plugin_get_orders',
        'permission_callback' => function () {
            return current_user_can( 'manage_options' );
        },
    ) );
} );

سه نکتهٔ حیاتی در این کد: اول، namespace با نسخه (my-plugin/v1) تا بتوانید در آینده بدون شکستن کلاینت‌های قدیمی، نسخهٔ جدید بسازید. دوم، همیشه permission_callback را پر کنید — نبود آن، یکی از جدی‌ترین حفره‌های امنیتی است. سوم، تابع callback باید خروجی را با rest_ensure_response یا آرایه بازگرداند تا وردپرس آن را به JSON تبدیل کند. برای درک کامل این الگو در معماری افزونه‌ها، مقالهٔ ساختار فایل‌های یک افزونه استاندارد وردپرس و هوک‌های وردپرس چیستند و چگونه کار می‌کنند مرجع خوبی هستند.

جدول endpointهای پرکاربرد

Endpointمتدکاربردنیاز به احراز هویت
/wp/v2/postsGETخواندن نوشته‌هاخیر
/wp/v2/postsPOSTایجاد نوشتهٔ جدیدبله
/wp/v2/pagesGETخواندن برگه‌هاخیر
/wp/v2/mediaPOSTآپلود فایل رسانهبله
/wp/v2/users/meGETاطلاعات کاربر فعلیبله
/wc/v3/productsGETمحصولات ووکامرسخیر/بله
/wc/v3/ordersPOSTایجاد سفارش جدیدبله

اشتباهات امنیتی و ساختاری رایج

  • نبود permission_callback در endpoint سفارشی: این یکی به‌تنهایی می‌تواند کل سایت را در دسترس هر کسی قرار دهد. همیشه این پارامتر را پر کنید، حتی اگر فقط می‌خواهید داده‌های عمومی بدهید.
  • نبود rate limiting: اگر endpoint نوشتن دارید، باید تعداد درخواست‌ها از هر IP محدود باشد. بدون این، یک حملهٔ خودکار می‌تواند هزاران نوشتهٔ هرز در دیتابیس شما بسازد.
  • افشای داده‌های حساس در پاسخ: endpoint پیش‌فرض کاربران اطلاعاتی مثل ایمیل را برمی‌گرداند. اگر لازم نیست، آن endpoint را با rest_endpoints حذف کنید.
  • نبود نسخه‌بندی: اگر روزی ساختار پاسخ را عوض کنید، کلاینت‌های قدیمی می‌شکنند. از همان اول namespace با نسخه انتخاب کنید.
  • بازگرداندن خطای عمومی: پیام‌های خطای دقیق و مفید بازگردانید (مثلاً با WP_Error) تا اشکال‌زدایی برای تیم‌های بعدی ساده‌تر شود.

از دید توسعه‌دهنده ارشد: REST API به‌عنوان لایهٔ قرارداد

در سطح معماری، REST API را باید یک «قرارداد» بین وردپرس و مصرف‌کننده‌های بیرونی در نظر بگیرید. این قرارداد، در گذر زمان بدون تغییر باقی می‌ماند حتی اگر دیتابیس یا ساختار داخلی تغییر کند — به شرطی که شما از نسخه‌بندی درست استفاده کنید. الگوی microservice‌ای که در پروژه‌های بزرگ توصیه می‌کنم، دقیقاً بر همین اصل سوار است: هر دامنه (محصول، سفارش، مشتری، پرداخت) یک namespace مستقل دارد و هر namespace نسخهٔ خودش را دارد.

نکتهٔ کلیدی دوم، کارایی است. REST API در وردپرس، از همان مکانیزم کوئری‌های WP_Query استفاده می‌کند؛ بنابراین اگر endpoint شما به‌طور پیش‌فرض نوشته‌های یک دستهٔ خاص را برمی‌گرداند، در واقع یک کوئری به دیتابیس می‌زند. اگر اپ موبایل شما در هر لود صفحه، پنج endpoint مختلف را صدا بزند و هر کدام یک کوئری سنگین داشته باشند، تجربهٔ کاربر به‌سرعت خراب می‌شود. سه تکنیک که در پروژه‌های واقعی به‌کار می‌گیرم: کش کردن پاسخ‌های GET در لایهٔ CDN یا در transientهای وردپرس، استفاده از _fields برای کاهش حجم، و ساخت endpointهای ترکیبی که چند داده را در یک درخواست برمی‌گردانند (شبیه الگوی GraphQL). مقایسهٔ این دو رویکرد را در تفاوت REST و GraphQL آورده‌ام.

نکتهٔ سوم، امنیت در لایهٔ قرارداد است. در پروژه‌های حساس، توصیه می‌کنم به‌جای تکیه بر یک توکن ثابت، از توکن‌های کوتاه‌مدت (مثلاً JWT با انقضای ۱۵ دقیقه) به‌همراه refresh token استفاده کنید. این الگو اگرچه پیچیده‌تر است، در اپلیکیشن‌های موبایلی که روی دستگاه‌های کاربران نصب می‌شوند، تفاوت امنیتی قابل‌توجهی ایجاد می‌کند. برای مطالعهٔ بیشتر در این زمینه، امنیت API و چگونه REST API امن بسازیم؟ مسیر طبیعی بعدی هستند. در نهایت، نکته‌ای که در پروژه‌های زیاد به آن رسیده‌ام: REST API وردپرس، اگر درست طراحی شود، می‌تواند یک لایهٔ یکپارچه‌سازی حرفه‌ای برای کل کسب‌وکار باشد — نه فقط یک ابزار فنی. ولی اگر روی آن بدون قرارداد نسخه‌بندی، بدون rate limiting و بدون مستندسازی کار کنید، در شش ماه به یک بدهی فنی سنگین تبدیل می‌شود که هر تغییر جدید، ریسک شکستن اپ موبایل یا سرویس بیرونی را به همراه دارد. یکی از عادت‌هایی که در تیم‌های حرفه‌ای دیدم و امروز خودم هم روی همهٔ پروژه‌ها اجرا می‌کنم: مستندسازی endpointهای سفارشی با ابزارهایی مثل Swagger، از همان روز اول. این مستندات، هم برای تیم فرانت‌اند ارزشمند است و هم برای هر توسعه‌دهنده‌ای که دو سال بعد به پروژه اضافه می‌شود. مسیر دقیق مستندسازی در مستندسازی REST API با Swagger آمده است.

اگر روی پروژه‌ای با چالش خاصی در REST API مواجه شده‌اید — مثلاً همگام‌سازی دو طرفه با یک سرویس انبار، یا مدیریت نرخ درخواست در اپ موبایل — سناریوی دقیقش را در دیدگاه بنویسید. تجربه‌های واقعی در این حوزه، همان‌قدر که برای من در پروژه‌های بعدی ارزش داشت، می‌تواند برای خوانندهٔ بعدی هم ارزشمند باشد. 🔌