Last active
April 2, 2024 03:44
-
-
Save rheinardkorf/0daa5531c60a6c8733b805f29f4d20c1 to your computer and use it in GitHub Desktop.
Example WordPress Proxy Layer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Init Proxy endpoints. | |
* | |
* @return void | |
*/ | |
public function rest_api_init() { | |
/** | |
* Proxy for GET requests. | |
*/ | |
register_rest_route( | |
$this->proxy_base, '/.*', [ | |
'methods' => \WP_REST_Server::READABLE, | |
'callback' => [ $this, 'get_request' ], | |
// @TODO: Add extra layers in here. | |
'permission_callback' => '__return_true', | |
] | |
); | |
} | |
/** | |
* Proxy GET requests. | |
* | |
* @param \WP_REST_Request $request Proxied request. | |
* | |
* @return \WP_REST_Response | |
*/ | |
public function get_request( \WP_REST_Request $request ) { | |
/** | |
* Use for whitelisting/blacklisting. | |
*/ | |
$response = apply_filters( $this->namespace . '/proxy/response_override', false, $request ); | |
if ( $response ) { | |
return $response; | |
} | |
/** | |
* @param \WP_REST_Request $request Original request. | |
*/ | |
$request = apply_filters( $this->namespace . '/proxy/request', $request ); | |
/** | |
* @param \WP_REST_Request $request API request. | |
*/ | |
do_action( $this->namespace . '/proxy/request_received', $request ); | |
// Get the route. | |
$route = $this->route( $request ); | |
/** | |
* Pre-fetch results. Can be from database or from cache. | |
* | |
* @param array $ Empty array. | |
* @param string $route The third-party API route to request. | |
* @param \WP_REST_Request $request API request. | |
*/ | |
$result = apply_filters( $this->namespace . '/proxy/result_pre', [], $route, $request ); | |
// We have no results, use the third-party API. | |
if ( empty( $result ) ) { | |
// Proxy the request. | |
$response = wp_remote_get( | |
$route, | |
[ | |
/** | |
* Filter the request headers. | |
* | |
* @param array $ Header KV pairs. | |
* @param string $route Route requested. | |
* @param \WP_REST_Request $request API request. | |
*/ | |
'headers' => apply_filters( $this->namespace . '/proxy/request_headers', [], $route, $request ), | |
] | |
); | |
/** | |
* Raw API response received. | |
* | |
* @param object|array $response Response from third-party API. | |
* @param string $route Route requested. | |
* @param \WP_REST_Request $request API request. | |
*/ | |
do_action( $this->namespace . '/proxy/raw_response_received', $response, $route, $request ); | |
$result = json_decode( $response['body'], true ); | |
/** | |
* Do something with the response before it is returned. E.g. Import the product(s) and/or cache it. | |
* | |
* @param array|\WP_Error $result Result from API call. | |
* @param string $route Route requested. | |
* @param \WP_REST_Request $request API request. | |
*/ | |
do_action( $this->namespace . '/proxy/response_received', $result, $route, $request ); | |
} | |
/** | |
* Filter the response results before returning it. | |
* | |
* @param array|\WP_Error $result Result from API call. | |
* @param string $route Route requested. | |
* @param \WP_REST_Request $request API request. | |
*/ | |
$result = apply_filters( $this->namespace . '/proxy/result', $result, $route, $request ); | |
$rest_response = new \WP_REST_Response( $result ); | |
/** | |
* Filter the WordPress REST response before it gets dispatched. | |
* | |
* @param \WP_REST_Response $rest_response Response to send back to request.. | |
* @param string $route Route requested. | |
* @param \WP_REST_Request $request API request. | |
*/ | |
$rest_response = apply_filters( $this->namespace . '/proxy/rest_response', $rest_response, $route, $request ); | |
return rest_ensure_response( $rest_response ); | |
} | |
/** | |
* Given a request, return the real URL. | |
* | |
* @param \WP_REST_Request $request The request. | |
* | |
* @return string | |
*/ | |
private function route( \WP_REST_Request $request ) { | |
$route = str_replace( '/' . $this->proxy_base . '/', '', $request->get_route() ); | |
$route = sprintf( '%s%s', trailingslashit( $this->config['api.host'] ), $route ); | |
$route = add_query_arg( $request->get_query_params(), $route ); | |
return $route; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment