WordPress REST API入门:从零开始构建你的第一个API接口
引言
WordPress REST API 是 WordPress 4.7 版本引入的重要功能,它为 WordPress 提供了强大的 RESTful 接口支持。通过 REST API,你可以使用 HTTP 请求来获取、创建、更新和删除 WordPress 内容,这为构建现代 Web 应用、移动应用和单页应用(SPA)提供了无限可能。本文将带你从零开始,学习如何使用 WordPress REST API。
一、REST API 基础
什么是 REST API?
REST(Representational State Transfer)是一种软件架构风格,它定义了一组约束和原则,用于设计网络应用程序接口。WordPress REST API 允许你通过发送 HTTP 请求来与 WordPress 站点交互,返回 JSON 格式的数据。
REST API 的优势
- 前后端分离:可以使用现代前端框架(React、Vue、Angular)构建用户界面
- 移动应用开发:为 iOS、Android 应用提供数据接口
- 跨平台集成:与其他系统和服务集成
- 灵活的数据获取:只获取需要的数据,减少带宽消耗
二、REST API 核心概念
端点(Endpoints)
端点是 REST API 中可以访问的特定 URL,每个端点对应特定的功能:
# 获取文章列表
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}路由(Routes)
路由是端点的路径,WordPress REST API 使用以下格式:
/wp-json/{namespace}/{route}wp-json:REST API 的基础路径wp/v2:WordPress 核心的命名空间和版本posts:具体的资源路由
请求方法
REST API 使用标准的 HTTP 请求方法:
- GET:获取资源
- POST:创建资源
- PUT/PATCH:更新资源
- DELETE:删除资源
三、使用 REST API 获取数据
1. 获取文章列表
使用 JavaScript 获取文章列表:
// 获取最新的10篇文章
fetch('https://your-site.com/wp-json/wp/v2/posts')
.then(response => response.json())
.then(posts => {
console.log('文章列表:', posts);
posts.forEach(post => {
console.log(`标题: ${post.title.rendered}`);
console.log(`作者: ${post.author}`);
console.log(`发布时间: ${post.date}`);
});
});2. 获取指定文章
// 获取ID为1的文章
fetch('https://your-site.com/wp-json/wp/v2/posts/1')
.then(response => response.json())
.then(post => {
console.log('文章标题:', post.title.rendered);
console.log('文章内容:', post.content.rendered);
console.log('文章摘要:', post.excerpt.rendered);
});3. 查询参数
使用查询参数过滤和排序数据:
// 获取分类ID为3的文章,按标题排序,每页5篇
fetch('https://your-site.com/wp-json/wp/v2/posts?categories=3&orderby=title&per_page=5')
.then(response => response.json())
.then(posts => {
console.log('分类文章:', posts);
});
// 搜索包含"WordPress"的文章
fetch('https://your-site.com/wp-json/wp/v2/posts?search=WordPress')
.then(response => response.json())
.then(posts => {
console.log('搜索结果:', posts);
});四、常用资源端点
文章(Posts)
// 获取文章
GET /wp-json/wp/v2/posts
// 参数说明
// - page: 页码
// - per_page: 每页数量(默认10,最大100)
// - search: 搜索关键词
// - categories: 分类ID,逗号分隔
// - tags: 标签ID,逗号分隔
// - author: 作者ID
// - orderby: 排序字段(date, title, author, etc.)
// - order: 排序方式(asc, desc)
// - status: 文章状态(publish, draft, pending, etc.)页面(Pages)
// 获取页面列表
GET /wp-json/wp/v2/pages
// 获取单个页面
GET /wp-json/wp/v2/pages/{id}分类(Categories)
// 获取分类列表
GET /wp-json/wp/v2/categories
// 获取单个分类
GET /wp-json/wp/v2/categories/{id}
// 创建分类(需要认证)
POST /wp-json/wp/v2/categories标签(Tags)
// 获取标签列表
GET /wp-json/wp/v2/tags
// 获取单个标签
GET /wp-json/wp/v2/tags/{id}用户(Users)
// 获取用户列表
GET /wp-json/wp/v2/users
// 获取单个用户
GET /wp-json/wp/v2/users/{id}
// 获取当前用户(需要认证)
GET /wp-json/wp/v2/users/me媒体(Media)
// 获取媒体列表
GET /wp-json/wp/v2/media
// 获取单个媒体项
GET /wp-json/wp/v2/media/{id}
// 上传媒体(需要认证)
POST /wp-json/wp/v2/media五、认证与权限
1. Cookie 认证
对于 WordPress 站点内的请求,可以使用 Cookie 认证:
// 在 WordPress 主题或插件中使用
fetch('/wp-json/wp/v2/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': wpApiSettings.nonce // WordPress 提供的 nonce
},
body: JSON.stringify({
title: '新文章标题',
content: '文章内容',
status: 'publish'
})
})
.then(response => response.json())
.then(post => {
console.log('文章已创建:', post);
});2. 应用密码认证
对于外部应用,可以使用应用密码:
// 使用应用密码进行基本认证
const username = 'your-username';
const applicationPassword = 'xxxx xxxx xxxx xxxx xxxx xxxx';
// 编码凭据
const credentials = btoa(`${username}:${applicationPassword}`);
fetch('https://your-site.com/wp-json/wp/v2/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${credentials}`
},
body: JSON.stringify({
title: '通过API创建的文章',
content: '这是通过REST API创建的文章内容',
status: 'publish'
})
})
.then(response => response.json())
.then(post => {
console.log('文章已创建:', post);
});3. JWT 认证
对于更复杂的应用,可以使用 JWT(JSON Web Token)认证:
// 首先获取令牌
fetch('https://your-site.com/wp-json/jwt-auth/v1/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: 'your-username',
password: 'your-password'
})
})
.then(response => response.json())
.then(data => {
const token = data.token;
// 使用令牌进行请求
return fetch('https://your-site.com/wp-json/wp/v2/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
title: 'JWT认证创建的文章',
content: '使用JWT令牌认证',
status: 'publish'
})
});
})
.then(response => response.json())
.then(post => {
console.log('文章已创建:', post);
});六、实战案例:创建文章
使用 JavaScript 创建文章
// 创建新文章
async function createPost(title, content, categoryId) {
try {
const response = await fetch('https://your-site.com/wp-json/wp/v2/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': wpApiSettings.nonce
},
body: JSON.stringify({
title: title,
content: content,
status: 'publish', // publish, draft, pending
categories: [categoryId],
tags: [1, 2, 3],
excerpt: '这是文章摘要'
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const post = await response.json();
console.log('文章创建成功:', post);
return post;
} catch (error) {
console.error('创建文章失败:', error);
throw error;
}
}
// 使用示例
createPost(
'我的第一篇API文章',
'这是通过REST API创建的文章内容,包含丰富的格式和样式。',
3 // 分类ID
);更新文章
// 更新现有文章
async function updatePost(postId, updates) {
try {
const response = await fetch(`https://your-site.com/wp-json/wp/v2/posts/${postId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': wpApiSettings.nonce
},
body: JSON.stringify(updates)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const post = await response.json();
console.log('文章更新成功:', post);
return post;
} catch (error) {
console.error('更新文章失败:', error);
throw error;
}
}
// 使用示例
updatePost(123, {
title: '更新后的文章标题',
content: '更新后的文章内容',
status: 'publish'
});删除文章
// 删除文章
async function deletePost(postId, forceDelete = false) {
try {
const response = await fetch(`https://your-site.com/wp-json/wp/v2/posts/${postId}?force=${forceDelete}`, {
method: 'DELETE',
headers: {
'X-WP-Nonce': wpApiSettings.nonce
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
console.log('文章删除成功:', result);
return result;
} catch (error) {
console.error('删除文章失败:', error);
throw error;
}
}
// 使用示例
deletePost(123, true); // 永久删除
deletePost(123, false); // 移到回收站七、自定义 REST API 端点
1. 创建自定义端点
在主题或插件中创建自定义 API 端点:
<?php
// 注册自定义 REST 路由
add_action('rest_api_init', function () {
// 获取热门文章的自定义端点
register_rest_route('my-plugin/v1', '/popular-posts', array(
'methods' => 'GET',
'callback' => 'my_plugin_get_popular_posts',
'permission_callback' => '__return_true' // 允许公开访问
));
// 获取用户统计的自定义端点(需要认证)
register_rest_route('my-plugin/v1', '/user-stats', array(
'methods' => 'GET',
'callback' => 'my_plugin_get_user_stats',
'permission_callback' => function () {
return current_user_can('read');
}
));
});
// 热门文章回调函数
function my_plugin_get_popular_posts($request) {
// 获取参数
$count = $request->get_param('count') ?: 5;
// 查询热门文章
$args = array(
'post_type' => 'post',
'posts_per_page' => $count,
'meta_key' => 'post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC'
);
$posts = get_posts($args);
// 准备响应数据
$data = array();
foreach ($posts as $post) {
$data[] = array(
'id' => $post->ID,
'title' => $post->post_title,
'views' => get_post_meta($post->ID, 'post_views_count', true),
'link' => get_permalink($post->ID)
);
}
return new WP_REST_Response($data, 200);
}
// 用户统计回调函数
function my_plugin_get_user_stats($request) {
$user_id = get_current_user_id();
$stats = array(
'user_id' => $user_id,
'post_count' => count_user_posts($user_id),
'comment_count' => get_comments(array(
'user_id' => $user_id,
'count' => true
)),
'registration_date' => get_the_author_meta('user_registered', $user_id)
);
return new WP_REST_Response($stats, 200);
}
?>2. 使用自定义端点
// 调用自定义端点
fetch('https://your-site.com/wp-json/my-plugin/v1/popular-posts?count=10')
.then(response => response.json())
.then(posts => {
console.log('热门文章:', posts);
});
// 获取用户统计(需要认证)
fetch('https://your-site.com/wp-json/my-plugin/v1/user-stats', {
headers: {
'X-WP-Nonce': wpApiSettings.nonce
}
})
.then(response => response.json())
.then(stats => {
console.log('用户统计:', stats);
});八、REST API 最佳实践
1. 缓存优化
// 使用缓存减少 API 请求
const cache = new Map();
async function fetchWithCache(url) {
if (cache.has(url)) {
console.log('从缓存获取:', url);
return cache.get(url);
}
const response = await fetch(url);
const data = await response.json();
// 缓存5分钟
cache.set(url, data);
setTimeout(() => cache.delete(url), 5 * 60 * 1000);
return data;
}
// 使用示例
fetchWithCache('https://your-site.com/wp-json/wp/v2/posts')
.then(posts => {
console.log('文章列表:', posts);
});2. 错误处理
// 完善的错误处理
async function safeFetch(url, options = {}) {
try {
const response = await fetch(url, options);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || `HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('API 请求失败:', error);
// 根据错误类型进行不同处理
if (error.message.includes('401')) {
console.log('需要重新认证');
} else if (error.message.includes('403')) {
console.log('权限不足');
} else if (error.message.includes('404')) {
console.log('资源不存在');
}
throw error;
}
}3. 分页处理
// 处理分页数据
async function getAllPosts() {
let allPosts = [];
let page = 1;
const perPage = 100;
while (true) {
const response = await fetch(
`https://your-site.com/wp-json/wp/v2/posts?page=${page}&per_page=${perPage}`
);
// 获取总页数
const totalPages = parseInt(response.headers.get('X-WP-TotalPages'), 10);
const posts = await response.json();
allPosts = allPosts.concat(posts);
if (page >= totalPages) {
break;
}
page++;
}
return allPosts;
}九、安全注意事项
1. 权限检查
<?php
// 始终进行权限检查
register_rest_route('my-plugin/v1', '/delete-post', array(
'methods' => 'POST',
'callback' => 'my_plugin_delete_post',
'permission_callback' => function ($request) {
// 检查用户是否登录
if (!is_user_logged_in()) {
return new WP_Error(
'rest_not_logged_in',
'您需要登录才能执行此操作',
array('status' => 401)
);
}
// 检查用户权限
if (!current_user_can('delete_posts')) {
return new WP_Error(
'rest_forbidden',
'您没有权限执行此操作',
array('status' => 403)
);
}
return true;
}
));
?>2. 数据验证和清理
<?php
function my_plugin_create_post($request) {
// 验证和清理输入数据
$title = sanitize_text_field($request->get_param('title'));
$content = wp_kses_post($request->get_param('content'));
if (empty($title)) {
return new WP_Error(
'rest_invalid_param',
'文章标题不能为空',
array('status' => 400)
);
}
// 创建文章
$post_id = wp_insert_post(array(
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish'
));
if (is_wp_error($post_id)) {
return $post_id;
}
return new WP_REST_Response(array(
'message' => '文章创建成功',
'post_id' => $post_id
), 200);
}
?>3. 速率限制
<?php
// 添加速率限制
add_action('rest_api_init', function () {
// 简单的速率限制实现
register_rest_route('my-plugin/v1', '/action', array(
'methods' => 'POST',
'callback' => 'my_plugin_rate_limited_action',
'permission_callback' => '__return_true'
));
});
function my_plugin_rate_limited_action($request) {
$user_id = get_current_user_id() ?: $_SERVER['REMOTE_ADDR'];
$transient_key = 'rate_limit_' . md5($user_id);
// 检查是否在限制期内
if (get_transient($transient_key)) {
return new WP_Error(
'rest_too_many_requests',
'请求过于频繁,请稍后再试',
array('status' => 429)
);
}
// 设置1分钟的限制
set_transient($transient_key, true, 60);
// 执行实际操作
return new WP_REST_Response(array('message' => '操作成功'), 200);
}
?>十、总结与扩展
你已经学会了:
- ✅ WordPress REST API 的基础概念
- ✅ 使用 REST API 获取和操作数据
- ✅ 认证和权限管理
- ✅ 创建自定义 API 端点
- ✅ REST API 最佳实践
- ✅ 安全注意事项
下一步可以学习:
- GraphQL 集成:使用 WPGraphQL 插件提供 GraphQL API
- WebSockets:实现实时数据更新
- OAuth 2.0:实现更复杂的认证流程
- API 版本管理:管理 API 的版本演进
- API 文档:使用 Swagger/OpenAPI 生成 API 文档
推荐资源:
希望这篇教程能帮助你入门 WordPress REST API。REST API 是现代 WordPress 开发的重要工具,掌握它将为你的开发工作带来极大的灵活性和可能性。
Happy Coding! 🚀