各位码农朋友们,早上好!今天咱们来聊聊 WordPress 里那些让人又爱又恨的 REST API 路由。说“爱”,是因为它让我们能用各种前端框架,甚至其他语言的程序,轻松跟 WordPress 后台“眉来眼去”;说“恨”,是因为有时搞不清楚那些参数,注册半天也跑不通。
好啦,废话不多说,今天咱们就深入剖析一下 register_rest_route()
这个函数,看看它到底是怎么工作的,以及怎么用它来注册我们自己的 API 路由。
一、register_rest_route()
函数的基本结构
register_rest_route()
函数,顾名思义,就是用来注册 REST API 路由的。它的基本结构是这样的:
register_rest_route( string $namespace, string $route, array $args = array(), bool $override = false )
咱们一个个参数来解释:
-
$namespace
(字符串): 这个参数就像一个“门牌号”,用来区分不同的 API 集合。 比如说,WordPress 内置的 API 路由都在wp/v2
这个命名空间下。 我们自己的 API 路由,最好也起一个有意义的命名空间,比如my-plugin/v1
。 命名空间必须符合正则表达式^[a-zA-Z0-9_-]+$
。 简单来说,就是只能包含字母、数字、下划线和短横线。 -
$route
(字符串): 这个参数是 API 路由的“路径”。 就像网站的 URL 一样,决定了访问哪个 API 端点。 比如/posts
就是获取文章列表的路由。 路由必须以斜杠/
开头。 路由中可以使用正则表达式来匹配参数,比如/posts/(?P<id>d+)
, 这里的(?P<id>d+)
就是一个正则表达式,用来匹配一个数字,并将其命名为id
。 -
$args
(数组): 这个参数最重要,它定义了 API 路由的行为,包括允许哪些 HTTP 方法、谁可以访问、以及如何处理请求。$args
数组里的常用键包括:methods
(字符串或数组): 指定允许的 HTTP 方法。 常用的方法有GET
、POST
、PUT
、DELETE
。 可以是一个字符串,比如'GET'
,也可以是一个数组,比如array( 'GET', 'POST' )
。callback
(回调函数): 指定处理 API 请求的回调函数。 这个函数必须接收一个WP_REST_Request
对象作为参数,并返回一个WP_REST_Response
对象,或者一个 WordPress 错误对象WP_Error
。permission_callback
(回调函数): 指定权限验证的回调函数。 这个函数必须返回true
如果用户有权限访问,否则返回false
或者一个WP_Error
对象。 如果没有指定permission_callback
, 默认情况下,只有登录用户才能访问。args
(数组): 定义 API 请求的参数。 可以指定参数的类型、是否必须、默认值等等。
-
$override
(布尔值): 这个参数决定了是否覆盖已存在的路由。 默认值是false
,表示不覆盖。 如果设置为true
, 就会覆盖同命名空间和路由下的已存在路由。 一般情况下,我们都设置为false
,以免不小心覆盖了其他插件或主题的路由。
二、一个简单的例子:获取文章标题
咱们先来一个最简单的例子,创建一个 API 路由,用来获取指定文章的标题。
add_action( 'rest_api_init', function () {
register_rest_route( 'my-plugin/v1', '/posts/(?P<id>d+)/title', array(
'methods' => 'GET',
'callback' => 'my_plugin_get_post_title',
'permission_callback' => '__return_true', // 允许所有人访问
) );
} );
function my_plugin_get_post_title( WP_REST_Request $request ) {
$id = $request['id']; // 获取文章 ID
$post = get_post( $id );
if ( empty( $post ) ) {
return new WP_Error( 'post_not_found', '找不到该文章', array( 'status' => 404 ) );
}
return rest_ensure_response( array( 'title' => get_the_title( $id ) ) );
}
这段代码做了什么呢?
add_action( 'rest_api_init', ... )
: 这个函数将一个匿名函数绑定到rest_api_init
钩子上。rest_api_init
钩子会在 REST API 初始化的时候被触发。 也就是说,这段代码会在 REST API 初始化的时候执行。register_rest_route( ... )
: 这就是注册 REST API 路由的关键函数。'my-plugin/v1'
: 命名空间,表示这个 API 属于my-plugin
插件的 v1 版本。'/posts/(?P<id>d+)/title'
: 路由。(?P<id>d+)
是一个正则表达式,用来匹配文章 ID。(?P<name>pattern)
是 PHP 的命名捕获组语法,它匹配pattern
并将匹配到的内容存储到name
变量中。array(...)
: 参数数组。'methods' => 'GET'
: 只允许GET
方法访问。'callback' => 'my_plugin_get_post_title'
: 指定处理请求的回调函数为my_plugin_get_post_title
。'permission_callback' => '__return_true'
: 允许所有人访问。__return_true
是一个 WordPress 内置的函数,总是返回true
。
my_plugin_get_post_title( WP_REST_Request $request )
: 这个函数是处理 API 请求的回调函数。$id = $request['id']
: 从请求对象中获取文章 ID。 注意,这里的'id'
就是路由中正则表达式(?P<id>d+)
中的id
。$post = get_post( $id )
: 根据文章 ID 获取文章对象。if ( empty( $post ) ) { ... }
: 如果文章不存在,返回一个WP_Error
对象。return rest_ensure_response( array( 'title' => get_the_title( $id ) ) )
: 如果文章存在,返回一个包含文章标题的WP_REST_Response
对象。rest_ensure_response()
函数确保返回值是一个WP_REST_Response
对象。
将这段代码放到你的主题的 functions.php
文件或者你的插件里,然后你就可以通过以下 URL 访问这个 API 路由了:
http://your-wordpress-site.com/wp-json/my-plugin/v1/posts/123/title
其中 123
是文章 ID。 访问这个 URL,你将会得到一个 JSON 格式的响应,包含文章的标题:
{
"title": "文章标题"
}
三、更复杂的例子:创建文章
接下来,咱们来一个更复杂的例子,创建一个 API 路由,用来创建文章。
add_action( 'rest_api_init', function () {
register_rest_route( 'my-plugin/v1', '/posts', array(
'methods' => 'POST',
'callback' => 'my_plugin_create_post',
'permission_callback' => 'my_plugin_check_permission', // 检查权限
'args' => array(
'title' => array(
'required' => true,
'type' => 'string',
'description' => '文章标题',
),
'content' => array(
'required' => true,
'type' => 'string',
'description' => '文章内容',
),
'status' => array(
'required' => false,
'type' => 'string',
'default' => 'draft',
'enum' => array( 'draft', 'publish', 'pending', 'private' ),
'description' => '文章状态',
),
),
) );
} );
function my_plugin_create_post( WP_REST_Request $request ) {
$title = $request['title'];
$content = $request['content'];
$status = $request['status'];
$post_id = wp_insert_post( array(
'post_title' => $title,
'post_content' => $content,
'post_status' => $status,
) );
if ( is_wp_error( $post_id ) ) {
return $post_id; // 返回 WP_Error 对象
}
return rest_ensure_response( array( 'id' => $post_id ) );
}
function my_plugin_check_permission( WP_REST_Request $request ) {
if ( ! current_user_can( 'publish_posts' ) ) {
return new WP_Error( 'rest_forbidden', '你没有权限创建文章', array( 'status' => 401 ) );
}
return true;
}
这个例子比之前的例子复杂一些,主要增加了以下内容:
'methods' => 'POST'
: 只允许POST
方法访问。 创建文章通常使用POST
方法。'permission_callback' => 'my_plugin_check_permission'
: 指定权限验证的回调函数为my_plugin_check_permission
。'args' => array(...)
: 定义 API 请求的参数。 这里定义了三个参数:title
、content
和status
。'title'
: 文章标题。'required' => true
: 表示这个参数是必须的。'type' => 'string'
: 表示这个参数的类型是字符串。'description' => '文章标题'
: 参数描述。 这个描述会显示在 API 文档中。
'content'
: 文章内容。'required' => true
: 表示这个参数是必须的。'type' => 'string'
: 表示这个参数的类型是字符串。'description' => '文章内容'
: 参数描述。
'status'
: 文章状态。'required' => false
: 表示这个参数不是必须的。'type' => 'string'
: 表示这个参数的类型是字符串。'default' => 'draft'
: 表示这个参数的默认值是draft
。'enum' => array( 'draft', 'publish', 'pending', 'private' )
: 表示这个参数的值只能是draft
、publish
、pending
或private
中的一个。'description' => '文章状态'
: 参数描述。
my_plugin_check_permission( WP_REST_Request $request )
: 这个函数是权限验证的回调函数。if ( ! current_user_can( 'publish_posts' ) ) { ... }
: 判断当前用户是否有publish_posts
权限。 如果没有,返回一个WP_Error
对象。current_user_can()
是 WordPress 内置的函数,用来判断用户是否具有指定的权限。
my_plugin_create_post( WP_REST_Request $request )
: 这个函数是处理 API 请求的回调函数。$title = $request['title']
: 从请求对象中获取文章标题。$content = $request['content']
: 从请求对象中获取文章内容。$status = $request['status']
: 从请求对象中获取文章状态。$post_id = wp_insert_post( ... )
: 创建文章。wp_insert_post()
是 WordPress 内置的函数,用来创建或更新文章。if ( is_wp_error( $post_id ) ) { ... }
: 如果创建文章失败,返回一个WP_Error
对象。return rest_ensure_response( array( 'id' => $post_id ) )
: 如果创建文章成功,返回一个包含文章 ID 的WP_REST_Response
对象。
要测试这个 API 路由,你可以使用 curl
命令:
curl -X POST
http://your-wordpress-site.com/wp-json/my-plugin/v1/posts
-H 'Content-Type: application/json'
-u 'username:password'
-d '{
"title": "新的文章标题",
"content": "新的文章内容",
"status": "publish"
}'
其中 username
和 password
是你的 WordPress 用户名和密码。 你需要替换 your-wordpress-site.com
为你的 WordPress 网站的域名。
如果创建文章成功,你将会得到一个 JSON 格式的响应,包含文章的 ID:
{
"id": 124
}
四、$args
数组详解
$args
数组是 register_rest_route()
函数中最关键的参数。 咱们来更详细地了解一下它的常用键:
键 | 类型 | 描述 |
---|---|---|
methods |
字符串/数组 | 指定允许的 HTTP 方法。 常用的方法有 GET 、POST 、PUT 、DELETE 。 |
callback |
回调函数 | 指定处理 API 请求的回调函数。 这个函数必须接收一个 WP_REST_Request 对象作为参数,并返回一个 WP_REST_Response 对象,或者一个 WordPress 错误对象 WP_Error 。 |
permission_callback |
回调函数 | 指定权限验证的回调函数。 这个函数必须返回 true 如果用户有权限访问,否则返回 false 或者一个 WP_Error 对象。 如果没有指定 permission_callback , 默认情况下,只有登录用户才能访问。 |
args |
数组 | 定义 API 请求的参数。 可以指定参数的类型、是否必须、默认值等等。 |
schema |
数组/回调函数 | 定义 API 响应的数据结构。 可以用来生成 API 文档,或者进行数据验证。 |
其中 args
键的值是一个数组,数组的每个元素都定义了一个参数。 参数的常用键包括:
键 | 类型 | 描述 |
---|---|---|
required |
布尔值 | 指定参数是否必须。 |
type |
字符串 | 指定参数的类型。 常用的类型有 string 、integer 、number 、boolean 、array 、object 。 |
description |
字符串 | 参数描述。 这个描述会显示在 API 文档中。 |
default |
任何类型 | 参数的默认值。 |
enum |
数组 | 指定参数的值只能是数组中的一个。 |
validate_callback |
回调函数 | 用于验证参数的回调函数。 这个函数接收参数的值作为输入,如果参数有效,则返回 true ,否则返回 false 或 WP_Error 对象。 |
sanitize_callback |
回调函数 | 用于清理参数的回调函数。 这个函数接收参数的值作为输入,并返回清理后的值。 |
五、一些需要注意的地方
- 命名空间: 选择一个有意义的命名空间,避免与其他插件或主题冲突。
- 权限验证: 一定要进行权限验证,避免未经授权的访问。
- 错误处理: 在回调函数中,要处理各种错误情况,并返回合适的
WP_Error
对象。 - 数据验证和清理: 对 API 请求的参数进行验证和清理,避免安全漏洞。
- API 文档: 使用
schema
参数定义 API 响应的数据结构,可以用来生成 API 文档。
六、总结
register_rest_route()
函数是 WordPress REST API 的核心。 掌握了它,你就可以轻松地创建自己的 API 路由,并与 WordPress 后台进行交互。 希望今天的讲座对你有所帮助。 记住,实践是检验真理的唯一标准,多写代码,多尝试,才能真正掌握 WordPress REST API。
下次再见!