📡 فصل ۱۱: REST API وردپرس
REST API وردپرس امکان میده دادههای سایت رو از خارج وردپرس بخونی و بنویسی - برای اپ موبایل، SPA با React، یا یکپارچگی با سرویسهای دیگه.
REST API وردپرس امکان میده دادههای سایت رو از خارج وردپرس بخونی و بنویسی – برای اپ موبایل، SPA با React، یا یکپارچگی با سرویسهای دیگه.
🌐 REST API چیست؟
از وردپرس ۴.۷ به بعد، یه REST API کامل به هسته اضافه شده. این API بهصورت پیشفرض در آدرس /wp-json/ در دسترسه.
تست کن!
توی مرورگر برو به: https://yoursite.com/wp-json/
یه JSON بزرگ میبینی که همه route ها رو لیست کرده.
کاربردهای REST API
- ساخت اپ موبایل با Flutter/React Native (مرتبط با پروژه آپادانا!)
- ساخت SPA با React/Vue که از وردپرس بهعنوان backend استفاده کنه
- یکپارچگی با سرویسهای دیگه (CRM، ERP)
- انتشار خودکار محتوا
- گزارشگیری و آنالیز
میتونی از REST API برای ساخت اپ Flutter استفاده کنی – دقیقاً همون کاری که داری انجام میدی! استک: WordPress + WooCommerce + REST API + Flutter.
📍 endpoint های پیشفرض
نوشتهها
| متد | endpoint | عملکرد |
|---|---|---|
| GET | /wp-json/wp/v2/posts |
لیست نوشتهها |
| GET | /wp-json/wp/v2/posts/{id} |
یک نوشته |
| POST | /wp-json/wp/v2/posts |
افزودن نوشته |
| PUT | /wp-json/wp/v2/posts/{id} |
ویرایش نوشته |
| DELETE | /wp-json/wp/v2/posts/{id} |
حذف نوشته |
سایر منابع
/wp-json/wp/v2/pages– برگهها/wp-json/wp/v2/categories– دستهها/wp-json/wp/v2/tags– برچسبها/wp-json/wp/v2/users– کاربران/wp-json/wp/v2/media– رسانه/wp-json/wp/v2/comments– دیدگاهها
برای CPT
اگه CPT با show_in_rest => true ثبت شده باشه، خودکار توی API هست:
/wp-json/wp/v2/{post_type}
پارامترهای پرکاربرد
// تعداد و صفحه
GET /wp-json/wp/v2/posts?per_page=20&page=2
// مرتبسازی
GET /wp-json/wp/v2/posts?orderby=date&order=desc
// جستجو
GET /wp-json/wp/v2/posts?search=وردپرس
// فیلتر دسته
GET /wp-json/wp/v2/posts?categories=5
// فیلد های خاص
GET /wp-json/wp/v2/posts?_fields=id,title,excerpt
// تعبیه شده (embed)
GET /wp-json/wp/v2/posts?_embed
🔐 احراز هویت
خوندن نوشتههای منتشرشده نیاز به احراز نداره. ولی نوشتن، خوندن پیشنویس و اطلاعات کاربر نیاز به authentication داره.
۱. Application Passwords (پیشفرض از 5.6)
راحتترین روش! توی پنل کاربر:
- برو به کاربران → پروفایل خودت
- پایین صفحه «Application Passwords» رو پیدا کن
- یه نام بذار (مثل «اپ آپادانا») و کلیک کن «Add New»
- یه کلید ۲۴ کاراکتری دریافت میکنی – یکبار نمایش داده میشه
- توی header درخواست استفاده کن:
curl --user "username:xxxx xxxx xxxx xxxx xxxx xxxx"
https://yoursite.com/wp-json/wp/v2/posts?status=draft
۲. JWT Authentication
برای اپهای موبایل – با افزونه JWT Authentication for WP REST API:
- افزونه رو نصب کن
- توی
wp-config.phpاین رو اضافه کن:
define('JWT_AUTH_SECRET_KEY', 'your-super-secret-key-here-min-32-chars');
define('JWT_AUTH_CORS_ENABLE', true);
۳. توی .htaccess:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
گرفتن توکن
POST /wp-json/jwt-auth/v1/token
Content-Type: application/json
{
"username": "admin",
"password": "your-password"
}
// Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
"user_email": "admin@site.com",
"user_nicename": "admin",
"user_display_name": "محمدعلی"
}
استفاده از توکن
GET /wp-json/wp/v2/posts?status=draft
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...
🛠 ساخت endpoint سفارشی
register_rest_route
add_action( 'rest_api_init', function () {
register_rest_route( 'icsd/v1', '/products/featured', array(
'methods' => 'GET',
'callback' => 'get_featured_products',
'permission_callback' => '__return_true', // عمومی
) );
} );
function get_featured_products( $request ) {
$args = array(
'post_type' => 'icsd_product',
'posts_per_page' => 10,
'meta_query' => array(
array(
'key' => '_featured',
'value' => '1',
),
),
);
$query = new WP_Query( $args );
$products = array();
foreach ( $query->posts as $post ) {
$products[] = array(
'id' => $post->ID,
'title' => $post->post_title,
'excerpt' => $post->post_excerpt,
'thumbnail' => get_the_post_thumbnail_url( $post->ID, 'medium' ),
'link' => get_permalink( $post->ID ),
'price' => get_post_meta( $post->ID, '_price', true ),
);
}
return rest_ensure_response( $products );
}
endpoint با parameter
add_action( 'rest_api_init', function () {
register_rest_route( 'icsd/v1', '/products/(?P<id>d+)', array(
'methods' => 'GET',
'callback' => 'get_single_product',
'args' => array(
'id' => array(
'validate_callback' => function( $param ) {
return is_numeric( $param );
},
),
),
'permission_callback' => '__return_true',
) );
} );
function get_single_product( $request ) {
$id = (int) $request['id'];
$post = get_post( $id );
if ( ! $post || $post->post_type !== 'icsd_product' ) {
return new WP_Error( 'not_found', 'محصول یافت نشد', array( 'status' => 404 ) );
}
return rest_ensure_response( array(
'id' => $post->ID,
'title' => $post->post_title,
'price' => get_post_meta( $post->ID, '_price', true ),
) );
}
// تست:
// GET /wp-json/icsd/v1/products/123
endpoint با POST
add_action( 'rest_api_init', function () {
register_rest_route( 'icsd/v1', '/contact', array(
'methods' => 'POST',
'callback' => 'handle_contact_form',
'permission_callback' => '__return_true',
'args' => array(
'name' => array(
'required' => true,
'sanitize_callback' => 'sanitize_text_field',
),
'email' => array(
'required' => true,
'sanitize_callback' => 'sanitize_email',
'validate_callback' => function( $value ) {
return is_email( $value );
},
),
'message' => array(
'required' => true,
'sanitize_callback' => 'sanitize_textarea_field',
),
),
) );
} );
function handle_contact_form( $request ) {
$name = $request->get_param( 'name' );
$email = $request->get_param( 'email' );
$message = $request->get_param( 'message' );
// ارسال ایمیل
$sent = wp_mail(
get_option( 'admin_email' ),
'فرم تماس از: ' . $name,
$message,
array( "From: $name <$email>" )
);
if ( $sent ) {
return rest_ensure_response( array(
'success' => true,
'message' => 'پیام ارسال شد!',
) );
}
return new WP_Error( 'send_failed', 'ارسال ناموفق', array( 'status' => 500 ) );
}
🛡 permission_callback
تابعی که چک میکنه آیا کاربر اجازه فراخوانی این endpoint رو داره یا نه.
// عمومی
'permission_callback' => '__return_true',
// فقط کاربر لاگین
'permission_callback' => function() {
return is_user_logged_in();
},
// فقط ادمین
'permission_callback' => function() {
return current_user_can( 'manage_options' );
},
// دسترسی خاص
'permission_callback' => function() {
return current_user_can( 'edit_posts' );
},
// با بررسی پارامتر
'permission_callback' => function( $request ) {
$post_id = $request['id'];
return current_user_can( 'edit_post', $post_id );
},
📲 مصرف API
JavaScript (Fetch API)
// خوندن نوشتهها
fetch( 'https://yoursite.com/wp-json/wp/v2/posts?per_page=5' )
.then( response => response.json() )
.then( posts => {
posts.forEach( post => {
console.log( post.title.rendered );
} );
} );
// با احراز هویت
fetch( 'https://yoursite.com/wp-json/wp/v2/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token,
},
body: JSON.stringify( {
title: 'نوشته از API',
content: 'محتوا...',
status: 'publish',
} ),
} )
.then( res => res.json() )
.then( data => console.log( data ) );
Flutter (Dart)
import 'package:http/http.dart' as http;
import 'dart:convert';
class ApiService {
final String baseUrl = 'https://yoursite.com/wp-json/wp/v2';
String? token;
// دریافت محصولات
Future<List<dynamic>> getProducts() async {
final response = await http.get(
Uri.parse('$baseUrl/icsd_product?per_page=20'),
);
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('خطا در دریافت محصولات');
}
}
// ورود
Future<void> login(String username, String password) async {
final response = await http.post(
Uri.parse('https://yoursite.com/wp-json/jwt-auth/v1/token'),
body: {'username': username, 'password': password},
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
token = data['token'];
}
}
// ساخت سفارش (با authentication)
Future<Map<String, dynamic>> createOrder(Map<String, dynamic> orderData) async {
final response = await http.post(
Uri.parse('$baseUrl/orders'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
},
body: jsonEncode(orderData),
);
return jsonDecode(response.body);
}
}
Python
import requests
# Application Password
auth = ('username', 'xxxx xxxx xxxx xxxx xxxx xxxx')
# لیست نوشتهها
response = requests.get(
'https://yoursite.com/wp-json/wp/v2/posts',
params={'per_page': 10, 'status': 'publish'},
auth=auth
)
posts = response.json()
# ساخت نوشته
new_post = {
'title': 'نوشته از پایتون',
'content': '<p>این نوشته با Python ساخته شده!</p>',
'status': 'publish',
'categories': [3],
}
response = requests.post(
'https://yoursite.com/wp-json/wp/v2/posts',
json=new_post,
auth=auth
)
print(response.json())
🎯 مثالهای کاربردی
جستجوی پیشرفته
register_rest_route( 'icsd/v1', '/search', array(
'methods' => 'GET',
'callback' => 'icsd_search',
'args' => array(
'q' => array( 'required' => true ),
),
'permission_callback' => '__return_true',
) );
function icsd_search( $request ) {
$query = sanitize_text_field( $request['q'] );
$results = new WP_Query( array(
's' => $query,
'post_type' => array( 'post', 'page', 'icsd_product' ),
'posts_per_page' => 20,
) );
$output = array();
foreach ( $results->posts as $post ) {
$output[] = array(
'title' => $post->post_title,
'type' => $post->post_type,
'link' => get_permalink( $post->ID ),
'thumbnail' => get_the_post_thumbnail_url( $post->ID, 'thumbnail' ),
);
}
return rest_ensure_response( $output );
}
📝 خلاصه فصل
- REST API در
/wp-json/در دسترسه - Application Password راحتترین احراز هویت
- JWT برای اپهای موبایل بهتره
- register_rest_route برای endpoint سفارشی
- permission_callback همیشه ست کن – حتی
__return_true - برای CPT خودت
show_in_rest => trueبذار