概述
API中的响应是我们想要的所有数据。如果我们在要求中犯了一个错误,我们的响应数据也应告知我们发生错误。WordPress REST API中的响应应返回我们要求的数据或错误消息。API中的响应由WP_REST_Response
班级,是API的三个基础设施类之一。
wp_rest_response
这WP_REST_Response
扩展WordPressWP_HTTP_Response
类,使我们访问响应标头,响应状态代码和响应数据。
// The following code will not do anything and just serves as a demonstration.
$response = new WP_REST_Response( 'This is some data' );
// To get the response data we can use this method. It should equal 'This is some data'.
$our_data = $response->get_data();
// To access the HTTP status code we can use this method. The most common status code is probably 200, which means OK!
$our_status = $response->get_status();
// To access the HTTP response headers we can use this method.
$our_headers = $response->get_headers();
以上非常简单,并向您展示如何从响应中获得所需的东西。这WP_REST_Response
将事情进一步。您可以访问匹配的路由以获取对回溯的响应,该响应来自响应。$response->get_matched_route()
。$response->get_matched_handler()
将返回为产生我们响应的端点注册的选项。这些对于记录API可能很有用。响应类还可以帮助我们解决错误处理。
错误处理
如果我们的要求出现了极大的错误,我们可以返回WP_Error
我们的端点回调中的对象解释了出了什么问题,这样:
// Register our mock batch endpoint.
function prefix_register_broken_route() {
register_rest_route( 'my-namespace/v1', '/broken', array(
// Supported methods for this endpoint. WP_REST_Server::READABLE translates to GET.
'methods' => WP_REST_Server::READABLE,
// Register the callback for the endpoint.
'callback' => 'prefix_get_an_error',
) );
}
add_action( 'rest_api_init', 'prefix_register_broken_route' );
/**
* Our registered endpoint callback. Notice how we are passing in $request as an argument.
* By default, the WP_REST_Server will pass in the matched request object to our callback.
*
* @param WP_REST_Request $request The current matched request object.
*/
function prefix_get_an_error( $request ) {
return new WP_Error( 'oops', esc_html__( 'This endpoint is currently broken, try another endpoint, I promise the API is cool! EEEK!!!!', 'my-textdomain' ), array( 'status' => 400 ) );
}
这是一个愚蠢的例子,但它涉及一些关键事情。最重要的是要理解的是,WordPress REST API将自动处理更改 wp_error 将对象进入包含您数据的HTTP响应。当您在
WP_Error
对象您的HTTP响应状态代码将具有该值。当您需要使用其他错误代码(例如404)来获取未找到的内容,或者403用于禁止访问时,这非常方便。我们要做的就是让我们的端点回调返回请求和WP_REST_Server
课程对我们来说将处理许多非常重要的事情。响应课程还有其他很酷的事情可以帮助我们,例如链接。
链接
如果我们想获得该帖子的帖子和第一个评论怎么办?我们会编写一个单独的端点来处理此用例吗?如果这样做,我们将需要开始添加大量端点来处理各种小用例,并且我们的API索引会很快肿。响应链接为我们提供了一种在API可以理解的资源之间形成关系的方法。API实现了用于资源链接的称为HAL的标准。让我们看一下我们的帖子和评论示例,最好为每个资源提供路线。
假设我们有ID = 1的帖子,并注释ID = 3。注释已分配给帖子1,因此实际上两个资源可以在路线上使用/my-namespace/v1/posts/1
和/my-namespace/v1/comments/3
。我们将添加指向响应的链接,以创建它们之间的关系。让我们首先从评论的角度看一下。
// Register our mock endpoints.
function prefix_register_my_routes() {
register_rest_route( 'my-namespace/v1', '/posts/(?P<id>[\d]+)', array(
// Supported methods for this endpoint. WP_REST_Server::READABLE translates to GET.
'methods' => WP_REST_Server::READABLE,
// Register the callback for the endpoint.
'callback' => 'prefix_get_rest_post',
) );
register_rest_route( 'my-namespace/v1', '/comments', array(
// Supported methods for this endpoint. WP_REST_Server::READABLE translates to GET.
'methods' => WP_REST_Server::READABLE,
// Register the callback for the endpoint.
'callback' => 'prefix_get_rest_comments',
// Register the post argument to limit results to a specific post parent.
'args' => array(
'post' => array(
'description' => esc_html__( 'The post ID that the comment is assigned to.', 'my-textdomain' ),
'type' => 'integer',
'required' => true,
),
),
) );
register_rest_route( 'my-namespace/v1', '/comments/(?P<id>[\d]+)', array(
// Supported methods for this endpoint. WP_REST_Server::READABLE translates to GET.
'methods' => WP_REST_Server::READABLE,
// Register the callback for the endpoint.
'callback' => 'prefix_get_rest_comment',
) );
}
add_action( 'rest_api_init', 'prefix_register_my_routes' );
// Grab a post.
function prefix_get_rest_post( $request ) {
$id = (int) $request['id'];
$post = get_post( $id );
$response = rest_ensure_response( array( $post ) );
$response->add_links( prefix_prepare_post_links( $post ) );
return $response;
}
// Prepare post links.
function prefix_prepare_post_links( $post ) {
$links = array();
$replies_url = rest_url( 'my-namespace/v1/comments' );
$replies_url = add_query_arg( 'post', $post->ID, $replies_url );
$links['replies'] = array(
'href' => $replies_url,
'embeddable' => true,
);
return $links;
}
// Grab a comments.
function prefix_get_rest_comments( $request ) {
if ( ! isset( $request['post'] ) ) {
return new WP_Error( 'rest_bad_request', esc_html__( 'You must specify the post parameter for this request.', 'my-text-domain' ), array( 'status' => 400 ) );
}
$data = array();
$comments = get_comments( array( 'post__in' => $request['post'] ) );
if ( empty( $comments ) ) {
return array();
}
foreach( $comments as $comment ) {
$response = rest_ensure_response( $comment );
$response->add_links( prefix_prepare_comment_links( $comment ) );
$data[] = prefix_prepare_for_collection( $response );
}
$response = rest_ensure_response( $data );
return $response;
}
// Grab a comment.
function prefix_get_rest_comment( $request ) {
$id = (int) $request['id'];
$post = get_comment( $id );
$response = rest_ensure_response( $comment );
$response->add_links( prefix_prepare_comment_links( $comment ) );
return $response;
}
// Prepare comment links.
function prefix_prepare_comment_links( $comment ) {
$links = array();
if ( 0 !== (int) $comment->comment_post_ID ) {
$post = get_post( $comment->comment_post_ID );
if ( ! empty( $post->ID ) ) {
$links['up'] = array(
'href' => rest_url( 'my-namespace/v1/posts/' . $comment->comment_post_ID ),
'embeddable' => true,
'post_type' => $post->post_type,
);
}
}
return $links;
}
/**
* Prepare a response for inserting into a collection of responses.
*
* This is lifted from WP_REST_Controller class in the WP REST API v2 plugin.
*
* @param WP_REST_Response $response Response object.
* @return array Response data, ready for insertion into collection data.
*/
function prefix_prepare_for_collection( $response ) {
if ( ! ( $response instanceof WP_REST_Response ) ) {
return $response;
}
$data = (array) $response->get_data();
$server = rest_get_server();
if ( method_exists( $server, 'get_compact_response_links' ) ) {
$links = call_user_func( array( $server, 'get_compact_response_links' ), $response );
} else {
$links = call_user_func( array( $server, 'get_response_links' ), $response );
}
if ( ! empty( $links ) ) {
$data['_links'] = $links;
}
return $data;
}
如上所示,我们正在使用链接来创建资源之间的关系。如果帖子有注释,我们的端点回调将添加指定“邮政参数”以匹配我们当前帖子ID的注释路由的链接。因此,如果您要遵循该路线,您现在将获得具有分配的发布ID的评论。如果您搜索评论,则每个评论将在帖子上具有链接点“`up”。使用HAL规范在链接中具有特殊含义。如果我们遵循链接进行评论,那么我们将退还给评论父母的帖子。链接非常棒,但是它会变得更好。
WordPress REST API还支持称为嵌入的内容。如果您在我们添加的两个链接中都注意到,我们指定了embeddable => true
。这使我们能够将链接的数据嵌入回复中。因此,如果我们想获取评论3及其分配的帖子,我们可以提出此请求https://ourawesomesite.com/wp-json/my-namespace/v1/comments/3?_embed
。这_embed
参数告诉API,我们希望我们请求的所有可嵌入资源链接也添加到API中。使用嵌入是性能增益,因为在一个HTTP请求中都处理了多个资源。
嵌入和链接的明智使用使WordPress REST API非常灵活且功能强大,可与WordPress互动。