REST API 开发
WordPress REST API 提供了强大的接口能力,允许外部应用与 WordPress 进行数据交互。
📚 REST API 基础
注册自定义 REST 路由
php
<?php
// 注册自定义 REST 路由
add_action('rest_api_init', 'my_register_custom_routes');
function my_register_custom_routes() {
// 注册路由
register_rest_route('my-plugin/v1', '/posts', array(
'methods' => 'GET',
'callback' => 'my_get_posts',
'permission_callback' => '__return_true',
));
// 带参数的路由
register_rest_route('my-plugin/v1', '/posts/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'my_get_post',
'permission_callback' => '__return_true',
));
}
// 回调函数
function my_get_posts($request) {
$args = array(
'post_type' => 'post',
'posts_per_page' => $request->get_param('per_page') ?: 10,
);
$posts = get_posts($args);
$data = array();
foreach ($posts as $post) {
$data[] = array(
'id' => $post->ID,
'title' => $post->post_title,
'content' => $post->post_content,
'date' => $post->post_date,
);
}
return new WP_REST_Response($data, 200);
}
function my_get_post($request) {
$post_id = $request->get_param('id');
$post = get_post($post_id);
if (!$post) {
return new WP_Error('not_found', '文章不存在', array('status' => 404));
}
return new WP_REST_Response(array(
'id' => $post->ID,
'title' => $post->post_title,
'content' => $post->post_content,
'date' => $post->post_date,
), 200);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
📝 完整示例
创建自定义文章类型的 REST API
php
<?php
// 注册自定义文章类型时添加 REST 支持
add_action('init', 'my_register_cpt_with_rest');
function my_register_cpt_with_rest() {
register_post_type('book', array(
'labels' => array(
'name' => '书籍',
'singular_name' => '书籍',
),
'public' => true,
'show_in_rest' => true, // 启用 REST API
'rest_base' => 'books', // REST 基础路径
'rest_controller_class' => 'WP_REST_Posts_Controller',
'supports' => array('title', 'editor', 'thumbnail'),
));
// 注册自定义分类法并启用 REST
register_taxonomy('genre', 'book', array(
'labels' => array('name' => '类型'),
'public' => true,
'show_in_rest' => true,
'rest_base' => 'genres',
));
}
// 添加自定义字段到 REST API
add_action('rest_api_init', 'my_add_custom_fields_to_rest');
function my_add_custom_fields_to_rest() {
// 注册书籍价格字段
register_post_meta('book', 'price', array(
'type' => 'number',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'absint',
));
// 注册书籍作者字段
register_post_meta('book', 'author_name', array(
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'sanitize_text_field',
));
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
添加权限回调
php
<?php
add_action('rest_api_init', 'my_protected_routes');
function my_protected_routes() {
register_rest_route('my-plugin/v1', '/admin/stats', array(
'methods' => 'GET',
'callback' => 'my_get_admin_stats',
'permission_callback' => function($request) {
return current_user_can('manage_options');
},
));
// 创建文章(需要登录)
register_rest_route('my-plugin/v1', '/posts', array(
'methods' => 'POST',
'callback' => 'my_create_post',
'permission_callback' => function($request) {
return current_user_can('edit_posts');
},
));
}
function my_get_admin_stats($request) {
$stats = array(
'total_posts' => wp_count_posts()->publish,
'total_users' => count_users()['total_users'],
);
return new WP_REST_Response($stats, 200);
}
function my_create_post($request) {
$title = $request->get_param('title');
$content = $request->get_param('content');
$post_id = wp_insert_post(array(
'post_title' => sanitize_text_field($title),
'post_content' => wp_kses_post($content),
'post_status' => 'draft',
'post_type' => 'post',
));
if (is_wp_error($post_id)) {
return $post_id;
}
return new WP_REST_Response(array(
'message' => '文章创建成功',
'post_id' => $post_id,
), 201);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
🔌 REST API 前端调用
使用 fetch
javascript
// GET 请求
fetch('/wp-json/my-plugin/v1/posts')
.then(response => response.json())
.then(data => console.log(data));
// GET 带参数
fetch('/wp-json/my-plugin/v1/posts?per_page=5')
.then(response => response.json())
.then(data => console.log(data));
// POST 请求
fetch('/wp-json/my-plugin/v1/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': wpApiSettings.nonce // 从 wp_localize_script 获取
},
body: JSON.stringify({
title: '新文章标题',
content: '文章内容...'
})
})
.then(response => response.json())
.then(data => console.log(data));1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
使用 WP API JS 客户端
javascript
// 初始化 API
const api = new wp.api.collections.Posts();
// 获取文章
api.fetch().then(posts => {
posts.forEach(post => {
console.log(post.title);
});
});
// 创建文章
api.create({
title: '新文章',
content: '内容...',
status: 'draft'
}).then(post => {
console.log('创建成功:', post.id);
});1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
🛡️ 安全最佳实践
php
<?php
// 1. 验证请求来源
add_action('rest_api_init', 'my_secure_routes');
function my_secure_routes() {
register_rest_route('my-plugin/v1', '/sensitive', array(
'methods' => 'POST',
'callback' => 'my_sensitive_data',
'permission_callback' => function($request) {
// 验证 nonce
$nonce = $request->get_header('X-WP-Nonce');
return wp_verify_nonce($nonce, 'wp_rest') && current_user_can('edit_posts');
},
));
}
// 2. 清理输入数据
function my_sanitize_input($request) {
$params = $request->get_json_params();
return array(
'title' => sanitize_text_field($params['title'] ?? ''),
'content' => wp_kses_post($params['content'] ?? ''),
'email' => sanitize_email($params['email'] ?? ''),
'url' => esc_url_raw($params['url'] ?? ''),
);
}
// 3. 限制请求频率
add_filter('rest_pre_dispatch', 'my_rate_limit', 10, 3);
function my_rate_limit($result, $server, $request) {
$ip = $_SERVER['REMOTE_ADDR'];
$key = 'rate_limit_' . md5($ip);
$count = get_transient($key) ?: 0;
if ($count > 60) { // 每分钟限制 60 次
return new WP_Error(
'rate_limit_exceeded',
'请求过于频繁,请稍后再试',
array('status' => 429)
);
}
set_transient($key, $count + 1, MINUTE_IN_SECONDS);
return $result;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
