Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection: Add REST support for jsonAPI endpoints #39432

Open
wants to merge 41 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
3a60d13
Connection: REST access for jsonAPI endpoints.
sergeymitr Sep 18, 2024
9b85565
Make endpoints provide their own REST route.
sergeymitr Sep 18, 2024
36368f0
Fix routes for name and slug requests.
sergeymitr Sep 18, 2024
61b021e
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Sep 23, 2024
8bfbadb
Add blog/user token verification.
sergeymitr Sep 23, 2024
6357e97
Add the version prefix to the endpoints.
sergeymitr Sep 23, 2024
9b5e5ae
Authenticate WP user if user token is provided, fix a few smaller aut…
sergeymitr Sep 24, 2024
20974a0
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Sep 25, 2024
52fe990
Fix a phpdoc typo.
sergeymitr Sep 25, 2024
549e826
Activate REST for the '/plugins' endpoint.
sergeymitr Sep 25, 2024
a3cc273
Improve REST authentication.
sergeymitr Sep 26, 2024
0d757d3
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Oct 11, 2024
4aaa656
Improve custom permission checking.
sergeymitr Oct 11, 2024
40eec5f
Add missing phpdoc.
sergeymitr Oct 11, 2024
b4836df
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Oct 16, 2024
ab97174
Implement response signature.
sergeymitr Oct 17, 2024
9ba813f
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Oct 24, 2024
bb92f7a
Make endpoints provide minimum the Jetpack version.
sergeymitr Oct 25, 2024
3db7335
Revert Post endpoints changes, we'll focus on the Plugins one for now.
sergeymitr Oct 25, 2024
9b3202f
Don't create REST route on WPCOM.
sergeymitr Oct 30, 2024
2e1ae27
Remove excessive REST authentication call.
sergeymitr Oct 30, 2024
8abca0d
Remove excessive admin.php loading.
sergeymitr Oct 31, 2024
e97dd90
Remove excessive fallback to blog token.
sergeymitr Nov 4, 2024
79fdce8
Improve comments for permission check callbacks.
sergeymitr Nov 4, 2024
22e01d7
Copy some code from XML-RPC's 'serve'.
sergeymitr Nov 7, 2024
01a8fbc
Handle locale.
sergeymitr Nov 13, 2024
a0ec6ce
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Nov 14, 2024
541cbe3
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Nov 19, 2024
8013673
Properly wrap REST JSON API errors.
sergeymitr Nov 19, 2024
b2b467a
Properly wrap REST response.
sergeymitr Nov 20, 2024
b9faed5
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Nov 21, 2024
eb68e2c
Fix phan error.
sergeymitr Nov 21, 2024
d2a9835
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Dec 3, 2024
bbb226a
Fix the empty output response.
sergeymitr Dec 3, 2024
debee21
Revert accidental debugging code commit.
sergeymitr Dec 3, 2024
95e1279
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Dec 10, 2024
2b2ff8c
Proper response wrapping and error handling.
sergeymitr Dec 13, 2024
a4806b7
Merge branch 'trunk' into add/json-api-direct-access
sergeymitr Dec 13, 2024
9d6f78a
Revert changes to the 'output()' method.
sergeymitr Dec 13, 2024
9739eaa
Mix some reverting issues.
sergeymitr Dec 13, 2024
4850259
Fix a type mismatch.
sergeymitr Dec 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions projects/plugins/jetpack/changelog/add-json-api-direct-access
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: other

Add REST support for jsonAPI endpoints.
16 changes: 16 additions & 0 deletions projects/plugins/jetpack/class.jetpack.php
Original file line number Diff line number Diff line change
Expand Up @@ -933,8 +933,11 @@ function ( $methods ) {
if ( $is_connection_ready ) {
require_once JETPACK__PLUGIN_DIR . '_inc/lib/class.jetpack-iframe-embed.php';
add_action( 'init', array( 'Jetpack_Iframe_Embed', 'init' ), 9, 0 );

require_once JETPACK__PLUGIN_DIR . '_inc/lib/class.jetpack-keyring-service-helper.php';
add_action( 'init', array( 'Jetpack_Keyring_Service_Helper', 'init' ), 9, 0 );

add_action( 'rest_api_init', array( $this, 'maybe_initialize_rest_jsonapi' ) );
}
}

Expand Down Expand Up @@ -6340,6 +6343,19 @@ public function run_initialize_tracking_action() {
do_action( 'jetpack_initialize_tracking' );
}

/**
* Initialize REST jsonAPI if needed.
*
* @return void
*/
public function maybe_initialize_rest_jsonapi() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that maybe it would make sense to shuffle things a bit so that we make this method consistent with json_api here.

require_once JETPACK__PLUGIN_DIR . 'class.json-api.php';
WPCOM_JSON_API::init( $method, $url, $post_body ); // And we register the routes via the api

// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( ! empty( $_GET['jsonapi'] ) && ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) ) {
define( 'WPCOM_JSON_API__BASE', 'public-api.wordpress.com/rest/v1' );
require_once JETPACK__PLUGIN_DIR . 'class.json-api-endpoints.php';
}
}

/**
* Run plugin post-activation actions if we need to.
*
Expand Down
56 changes: 56 additions & 0 deletions projects/plugins/jetpack/class.json-api-endpoints.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

use Automattic\Jetpack\Connection\Client;
use Automattic\Jetpack\Connection\Manager;
use Automattic\Jetpack\Status;

require_once __DIR__ . '/json-api-config.php';
Expand Down Expand Up @@ -124,6 +125,13 @@ abstract class WPCOM_JSON_API_Endpoint {
*/
public $path_labels = array();

/**
* The REST endpoint if available.
*
* @var bool
*/
public $rest_route = null;

/**
* Accepted query parameters
*
Expand Down Expand Up @@ -277,6 +285,11 @@ abstract class WPCOM_JSON_API_Endpoint {
*/
public $allow_fallback_to_jetpack_blog_token = false;

/**
* REST namespace.
*/
const REST_NAMESPACE = 'rest/v1';
sergeymitr marked this conversation as resolved.
Show resolved Hide resolved

/**
* Constructor.
*
Expand All @@ -300,6 +313,7 @@ public function __construct( $args ) {
'new_version' => WPCOM_JSON_API__CURRENT_VERSION,
'jp_disabled' => false,
'path_labels' => array(),
'rest_route' => null,
'request_format' => array(),
'response_format' => array(),
'query_parameters' => array(),
Expand Down Expand Up @@ -334,6 +348,7 @@ public function __construct( $args ) {
$this->method = $args['method'];
$this->path = $args['path'];
$this->path_labels = $args['path_labels'];
$this->rest_route = $args['rest_route'];
$this->min_version = $args['min_version'];
$this->max_version = $args['max_version'];
$this->deprecated = $args['deprecated'];
Expand Down Expand Up @@ -387,6 +402,10 @@ public function __construct( $args ) {
$this->example_response = $args['example_response'];

$this->api->add( $this );

if ( $this->rest_route ) {
$this->create_rest_route_for_endpoint();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should never happen on WPCOM :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, it feels like this logic would be better suited to be part of the api, aka WPCOM_JSON_API vs the endpoint definitions. Is there a reason you chose to add it here?

Copy link
Contributor Author

@sergeymitr sergeymitr Oct 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I added the "not WPCOM" condition: 9b3202f

Is there a reason you chose to add it here?

The REST endpoint belongs to the endpoint object, so that seems logical to me to let the endpoint object initialize it.
That way the whole logic is encapsulated within a single class, simplifying the code.

}
}

/**
Expand Down Expand Up @@ -2618,6 +2637,43 @@ public function get_amp_cache_origins( $siteurl ) {
);
}

/**
* Register a REST route for this jsonAPI endpoint.
*
* @return void
* @throws Exception The exception if something goes wrong.
*/
public function create_rest_route_for_endpoint() {
register_rest_route(
static::REST_NAMESPACE,
$this->rest_route,
array(
'methods' => $this->method,
'callback' => array( $this, 'rest_callback' ),
)
);
}

/**
* Handle the rest call.
*
* @param WP_REST_Request $request The request object.
*
* @return mixed|WP_Error
*/
public function rest_callback( WP_REST_Request $request ) {
$manager = new Manager( 'jetpack' );
if ( ! $manager->is_connected() ) {
return new WP_Error( 'site_not_connected' );
}

$blog_id = Jetpack_Options::get_option( 'id' );
return call_user_func_array(
array( $this, 'callback' ),
array_values( array( $this->path, $blog_id ) + $request->get_url_params() )
);
}

/**
* Return endpoint response
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
'$site' => '(int|string) Site ID or domain',
'$post_ID' => '(int) The post ID',
),
'rest_route' => '/posts/(?P<id>\d+)',

'allow_fallback_to_jetpack_blog_token' => true,

Expand All @@ -36,6 +37,7 @@
'$site' => '(int|string) Site ID or domain',
'$post_name' => '(string) The post name (a.k.a. slug)',
),
'rest_route' => '/posts/name/(?P<name>[\w_-]+)',

'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/en.blog.wordpress.com/posts/name:blogging-and-stuff',
)
Expand All @@ -54,6 +56,7 @@
'$site' => '(int|string) Site ID or domain',
'$post_slug' => '(string) The post slug (a.k.a. sanitized name)',
),
'rest_route' => '/posts/slug/(?P<slug>[\w_-]+)',

'allow_fallback_to_jetpack_blog_token' => true,

Expand Down
Loading