Two of my recent articles are about the WooCommerce REST API and the official PHP library from Automattic, which makes the usage of the API with PHP easier. This post describes a way to run multiple requests against a shop at the same time.
The problem when using the API with the official PHP library
If the API is used as I described in my recent posts, then every request pauses the program until the request was finished. If there are only a few requests or requests that depend on each other, that is not that bad, or the wanted behavior.
But if you want to fire API requests that could be bundled, for example, because they should add multiple products, then it would be cool to run those requests parallel. With that, the runtime could be reduced, but that is – as far as I know – not possible with the official PHP lib for the REST API.
The solution: the Requests library
The post »A Guide to Async HTTP Requests for WordPress« by Josh Pollock made me aware of the Requests library by Ryan McCue, that is part of WordPress core for some time now. With its requests_multiple()
method, it is possible to run multiple requests at once – exactly what we want.
For example, to make two parallel GET requests, the code could look something like that:
$requests_array = [
[
'url' => 'https://example.com/api-endpoint-1',
'type' => 'GET',
],
[
'url' => 'https://example.com/api-endpoint-2',
'type' => 'GET',
],
];
$responses = Requests::request_multiple( $requests_array );
Code language: PHP (php)
$responses
safes the result of both requests.
Usage of the Requests library with the WooCommerce API
A note to the following steps: I did not get it working locally, because request_multiple()
currently does not work with self-signed SSL certs (there is an option to deactivate the cert check, but it is not working with the method), and I failed with using OAuth 1 authentication. So the easiest way is to test it on a real server with a valid SSL certificate.
To communicate with the WooCommerce API, we need a URL of the following format (I think it is also possible to provide consumer_key
and consumer_secret
as HTTP headers, but I did not try that):
Code language: Bash (bash)https://example.com/wp-json/wc/v2/products/categories?consumer_key=ck_000&consumer_secret=cs_000
The first part until the products/categories
endpoint does not change while running requests against one shop; the same goes for both params consumer_key
and consumer_secret
.
We create a little helper function that returns a API URL for a provided endpoint:
/**
* Returns URL for accessing the provided WooCommerce REST API endpoint.
*
* @param string $endpoint API endpoint.
* @param array $parameters Optional parameters.
*
* @return string
*/
function build_api_url( $endpoint, $parameters = [] ) {
// Add trailing slash to URL.
$url = trailingslashit( 'https://example.com/wp-json/wc/v2/' ) . $endpoint;
$api_url = add_query_arg( \array_merge( $parameters, [
'consumer_key' => 'ck_000',
'consumer_secret' => 'cs_000',
] ), $url );
return $api_url;
}
Code language: PHP (php)
And now it is possible, for example to retrieve the product categories and attributes, with the following code:
// Make requests to get existing categories and attributes.
$requests = [
[
'url' => build_api_url( 'products/categories' ),
'type' => 'GET',
],
[
'url' => build_api_url( 'products/attributes' ),
'type' => 'GET',
]
];
$responses = Requests::request_multiple( $requests );
Code language: PHP (php)
To create multiple products, the product data could be looped and put into a temporary array, along with the request data. That array could look like that:
$tmp_requests_array[] = [
'url' => build_api_url( "products" ),
'type' => 'POST',
'data' => $prod_data,
];
Code language: PHP (php)
Where $prod_data
is the array of the product data like described in my article »Creating a WooCommerce product with PHP via the REST API«. After the products were looped and all requests are in the array, we run request_multiple()
with the array as the parameter. Maybe you should be a little careful not to send too many requests to the server at the same time.
One thing that currently does not work with requests_multiple()
too is providing user and password to access the API of a shop that is saved via .htaccess basic auth.