Skip to content

Instantly share code, notes, and snippets.

@rheinardkorf
Last active April 2, 2024 03:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rheinardkorf/0daa5531c60a6c8733b805f29f4d20c1 to your computer and use it in GitHub Desktop.
Save rheinardkorf/0daa5531c60a6c8733b805f29f4d20c1 to your computer and use it in GitHub Desktop.
Example WordPress Proxy Layer
<?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