各位观众老爷,大家好!今天咱们来聊聊 WordPress REST API 的 rest_api_init
钩子,看看它怎么帮咱们注册自定义路由,让 WordPress 的 API 变得更加强大,更加听话。
开场白:REST API,WordPress 的新玩具
话说 WordPress 越来越现代化,不仅仅是个博客系统了,还想做个内容管理平台(CMS),甚至是应用程序的后端。这就要用到 REST API 了。REST API 就像一个翻译官,让不同的程序(比如你的前端应用和 WordPress 后台)能够互相交流,互通有无。
WordPress 已经自带了一套 REST API,但是它提供的路由可能不够你用。这时候,就需要咱们自己动手,注册自定义路由,定制个性化的 API 端点。rest_api_init
钩子,就是咱们定制 API 的入口。
rest_api_init
:API 初始化时的秘密通道
rest_api_init
钩子是一个 action hook,它在 REST API 初始化的时候被触发。你可以把它理解成一个“秘密通道”,WordPress 会在特定的时刻打开这个通道,允许你添加自定义的 API 路由。
如何使用 rest_api_init
钩子?
使用 rest_api_init
钩子很简单,只需要以下几步:
- 定义一个函数: 这个函数将包含你注册自定义路由的代码。
- 将函数挂载到
rest_api_init
钩子上: 使用add_action()
函数将你的函数挂载到rest_api_init
钩子上。
// 定义注册自定义路由的函数
function my_register_routes() {
// 在这里注册你的自定义路由
}
// 将函数挂载到 rest_api_init 钩子上
add_action( 'rest_api_init', 'my_register_routes' );
就这么简单!现在,my_register_routes()
函数会在 REST API 初始化的时候被调用。
注册自定义路由的关键:register_rest_route()
注册自定义路由的核心函数是 register_rest_route()
。它接受三个参数:
- 命名空间(Namespace): 用于组织你的 API 路由,避免与其他插件的路由冲突。通常使用插件或主题的名称作为命名空间。
- 路由(Route): 定义 API 端点的 URL 路径。例如,
/my-plugin/v1/items
。 - 参数数组(Arguments Array): 包含路由的配置信息,比如处理请求的回调函数、请求方法、权限验证等。
register_rest_route(
'my-plugin/v1', // 命名空间
'/items', // 路由
array( // 参数数组
'methods' => 'GET', // 允许的请求方法
'callback' => 'my_get_items', // 处理请求的回调函数
'permission_callback' => '__return_true', // 权限验证回调函数
)
);
让我们详细解释一下参数数组中的几个关键选项:
methods
: 指定允许的 HTTP 请求方法。常用的方法包括GET
(获取数据)、POST
(创建数据)、PUT
(更新数据)、DELETE
(删除数据)。 可以使用单个字符串,例如'GET'
,也可以使用数组,例如array( 'GET', 'POST' )
。callback
: 指定处理 API 请求的回调函数。这个函数负责接收请求参数,处理业务逻辑,并返回响应数据。permission_callback
: 指定权限验证的回调函数。这个函数负责检查用户是否有权限访问该 API 端点。如果用户没有权限,应该返回false
或一个WP_Error
对象。如果用户有权限,应该返回true
。'__return_true'
表示允许所有用户访问(不建议在生产环境中使用)。
一个完整的例子:获取文章列表
假设我们要创建一个 API 端点,用于获取最新的 10 篇文章列表。 我们可以这样做:
function my_get_latest_posts( $request ) {
$args = array(
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
);
$posts = get_posts( $args );
$data = array();
foreach ( $posts as $post ) {
$data[] = array(
'id' => $post->ID,
'title' => $post->post_title,
'link' => get_permalink( $post->ID ),
);
}
return $data;
}
function my_register_routes() {
register_rest_route(
'my-plugin/v1',
'/latest-posts',
array(
'methods' => 'GET',
'callback' => 'my_get_latest_posts',
'permission_callback' => '__return_true', // 生产环境需要更严格的权限控制
)
);
}
add_action( 'rest_api_init', 'my_register_routes' );
在这个例子中:
my_get_latest_posts()
函数负责查询最新的 10 篇文章,并将它们转换为一个包含 ID、标题和链接的数组。register_rest_route()
函数将/my-plugin/v1/latest-posts
路由与my_get_latest_posts()
函数关联起来。add_action()
函数将my_register_routes()
函数挂载到rest_api_init
钩子上。
现在,你可以通过访问 your-wordpress-site.com/wp-json/my-plugin/v1/latest-posts
来获取最新的 10 篇文章列表。
处理请求参数:WP_REST_Request
对象
API 请求通常会包含一些参数,比如搜索关键词、分页信息等。 在你的回调函数中,你可以通过 WP_REST_Request
对象来获取这些参数。
WP_REST_Request
对象包含了请求的所有信息,包括:
get_params()
: 获取所有参数的数组。get_param( $name )
: 获取指定名称的参数值。get_query_params()
: 获取查询字符串参数的数组。get_body_params()
: 获取请求体参数的数组(通常用于POST
、PUT
等请求)。
例如:
function my_search_posts( $request ) {
$keyword = $request->get_param( 'keyword' ); // 获取名为 "keyword" 的参数
$args = array(
's' => $keyword, // 设置搜索关键词
);
$query = new WP_Query( $args );
$data = array();
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$data[] = array(
'id' => get_the_ID(),
'title' => get_the_title(),
'link' => get_permalink(),
);
}
wp_reset_postdata(); // 恢复全局文章数据
}
return $data;
}
function my_register_routes() {
register_rest_route(
'my-plugin/v1',
'/search',
array(
'methods' => 'GET',
'callback' => 'my_search_posts',
'permission_callback' => '__return_true', // 生产环境需要更严格的权限控制
'args' => array( // 定义参数
'keyword' => array(
'validate_callback' => 'rest_validate_request_arg', // 验证参数是否有效
'sanitize_callback' => 'sanitize_text_field', // 清理参数
'required' => true, // 参数是否必须
'description' => '搜索关键词', // 参数描述
),
),
)
);
}
add_action( 'rest_api_init', 'my_register_routes' );
在这个例子中:
my_search_posts()
函数从WP_REST_Request
对象中获取名为 "keyword" 的参数,并使用它来搜索文章。register_rest_route()
函数的args
数组定义了 "keyword" 参数的验证、清理和描述信息。
返回响应数据:WP_REST_Response
对象
你的回调函数应该返回一个 WP_REST_Response
对象或一个 WP_Error
对象。
WP_REST_Response
: 用于返回成功的响应数据。你可以使用它来设置响应状态码、头部信息和数据。WP_Error
: 用于返回错误信息。你可以使用它来设置错误代码、错误消息和错误数据。
function my_get_item( $request ) {
$id = $request->get_param( 'id' );
$post = get_post( $id );
if ( ! $post ) {
return new WP_Error( 'item_not_found', 'Item not found.', array( 'status' => 404 ) );
}
$data = array(
'id' => $post->ID,
'title' => $post->post_title,
'content' => $post->post_content,
);
$response = new WP_REST_Response( $data );
$response->set_status( 200 ); // 设置状态码
return $response;
}
function my_register_routes() {
register_rest_route(
'my-plugin/v1',
'/items/(?P<id>d+)', // 使用正则表达式定义路由,允许传入id参数
array(
'methods' => 'GET',
'callback' => 'my_get_item',
'permission_callback' => '__return_true',
'args' => array(
'id' => array(
'validate_callback' => 'rest_validate_request_arg',
'sanitize_callback' => 'absint',
'required' => true,
'description' => 'Item ID',
),
),
)
);
}
add_action( 'rest_api_init', 'my_register_routes' );
在这个例子中:
my_get_item()
函数尝试获取指定 ID 的文章。- 如果文章不存在,它会返回一个
WP_Error
对象,状态码为 404。 - 如果文章存在,它会返回一个
WP_REST_Response
对象,包含文章的 ID、标题和内容,状态码为 200。 - 路由中使用正则表达式
(?P<id>d+)
定义了一个名为id
的参数,它必须是一个数字。
权限验证:保护你的 API
权限验证是 REST API 安全的关键。 permission_callback
参数允许你定义一个回调函数,用于检查用户是否有权限访问该 API 端点。
以下是一些常见的权限验证方法:
- 检查用户是否已登录: 使用
is_user_logged_in()
函数。 - 检查用户是否具有特定的角色或权限: 使用
current_user_can()
函数。 - 使用 Nonce 验证: Nonce 是一种安全令牌,可以防止跨站请求伪造(CSRF)攻击。
function my_check_permission( $request ) {
if ( ! is_user_logged_in() ) {
return new WP_Error( 'rest_not_logged_in', 'You are not currently logged in.', array( 'status' => 401 ) );
}
if ( ! current_user_can( 'edit_posts' ) ) {
return new WP_Error( 'rest_forbidden', 'You do not have permission to edit posts.', array( 'status' => 403 ) );
}
return true;
}
function my_register_routes() {
register_rest_route(
'my-plugin/v1',
'/secure-endpoint',
array(
'methods' => 'POST',
'callback' => 'my_process_data',
'permission_callback' => 'my_check_permission', // 使用自定义权限验证函数
)
);
}
add_action( 'rest_api_init', 'my_register_routes' );
在这个例子中:
my_check_permission()
函数检查用户是否已登录,并且是否具有edit_posts
权限。- 如果用户未登录或没有权限,它会返回一个
WP_Error
对象,状态码分别为 401 和 403。 register_rest_route()
函数使用my_check_permission()
函数作为权限验证回调函数。
总结:rest_api_init
钩子,你的 API 定制利器
rest_api_init
钩子是 WordPress REST API 定制的关键。 通过它,你可以注册自定义路由,处理请求参数,返回响应数据,并进行权限验证。 掌握了这些技巧,你就可以创建出功能强大、安全可靠的 WordPress REST API,让你的 WordPress 站点更加灵活和可扩展。
表格总结:register_rest_route()
函数参数
参数 | 类型 | 描述 |
---|---|---|
$namespace |
string | 命名空间,用于组织你的 API 路由,避免与其他插件的路由冲突。 |
$route |
string | 路由,定义 API 端点的 URL 路径。例如,/my-plugin/v1/items 。可以使用正则表达式来定义动态路由,例如 /items/(?P<id>d+) 。 |
$args |
array | 参数数组,包含路由的配置信息。 |
$args['methods'] |
string/array | 指定允许的 HTTP 请求方法。常用的方法包括 GET 、POST 、PUT 、DELETE 。 |
$args['callback'] |
callable | 指定处理 API 请求的回调函数。这个函数负责接收请求参数,处理业务逻辑,并返回响应数据。 |
$args['permission_callback'] |
callable | 指定权限验证的回调函数。这个函数负责检查用户是否有权限访问该 API 端点。如果用户没有权限,应该返回 false 或一个 WP_Error 对象。如果用户有权限,应该返回 true 。 |
$args['args'] |
array | 定义路由参数的验证、清理和描述信息。每个参数都应该是一个数组,包含 validate_callback 、sanitize_callback 、required 和 description 等选项。 |
彩蛋:REST API 调试工具
调试 REST API 可能会比较麻烦。 幸运的是,有很多工具可以帮助你:
- Postman: 一个流行的 API 客户端,可以发送各种 HTTP 请求,并查看响应结果。
- Insomnia: 另一个强大的 API 客户端,功能类似于 Postman。
- 浏览器的开发者工具: 大多数浏览器都提供了开发者工具,可以用来查看网络请求和响应。
- WordPress REST API 插件: 有一些 WordPress 插件可以帮助你调试 REST API,比如 "REST API Toolbox"。
希望今天的讲座对大家有所帮助! 祝大家玩转 WordPress REST API,创造出更加精彩的应用!