Parallele Anfragen an die WooCommerce-REST-API mit der PHP-Requests-Bibliothek

In zwei kürzlich geschriebenen Artikeln bin ich bereits auf die REST-API von WooCommerce eingegangen, sowie auf einen PHP-Bibliothek von Automattic, die die Nutzung der API mit PHP vereinfacht. Hier stelle ich einen Weg vor, wie mehrere Anfragen gleichzeitig an den Shop gemacht werden können.

Das Problem bei der »normalen« Nutzung der API via PHP

Wenn die API so genutzt wird wie in meinen beiden Beiträgen geschrieben, dann läuft das PHP-Programm erst weiter, wenn der HTTP-Request fertig ist. Bei einigen wenigen Requests oder bei vielen einzelnen Requests, die alle direkt voneinander abhängen, ist das das gewünschte Verhalten.

Wenn allerdings API-Requests abgefeuert werden, die gebündelt werden könnten, weil beispielsweise mehrere Produkte angelegt werden sollen, dann wäre es schön diese parallel starten zu können, um die Laufzeit des Skripts verkürzen zu können. Das ist – soweit ich weiß – mit der offiziellen PHP-Bibliothek für die REST-API nicht möglich.

Die Lösung: Die Requests-Bibliothek

Über den Beitrag »A Guide to Async HTTP Requests for WordPress« von Josh Pollock bin ich auf die Requests-Bibliothek von Ryan McCue aufmerksam geworden, die seit einiger Zeit fester Bestandteil von WordPress ist. Über deren request_multiple()-Methode können mehrere HTTP-Requests parallel gemacht werden – perfekt also für das geplante Vorhaben.

Um zwei GET-Anfragen gleichzeitig zu starten, wird beispielsweise der folgende Code benötigt:

$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 );

In $responses sind dann die Ergebnisse der beiden Anfragen gespeichert.

Nutzung der Requests-Bibliothek für die WooCommerce-API

Für die nachfolgenden Schritte sei angemerkt: ich habe es nicht lokal zum Laufen gebracht, da request_multiple() momentan nicht mit selbst erstellten SSL-Zertifikaten funktioniert (normalerweise lässt sich die Prüfung unterbinden, ob es sich um ein vertrauenswürdiges Zertifikat handelt) und ich beim Versuch der Authentifizierung via OAuth1 gescheitert bin. Das einfachste ist, es auf einem richtigen Server mit gültigem SSL-Zertifikat auszuprobieren.

Um mit der WooCommerce-API zu kommunizieren, brauchen wir eine URL nach dem folgenden Format (consumer_key und consumer_secret könnten glaube ich auch über HTTP-Header übertragen werden, das habe ich mir aber nicht angeschaut):

https://example.com/wp-json/wc/v2/products/categories?consumer_key=ck_000&consumer_secret=cs_000

Der erste Teil bis zum Endpoint products/categories ist fest, und die beiden Parameter consumer_key und consumer_secret verändern sich bei der Kommunikation mit ein und demselben Shop auch nicht. Wir bauen uns der Übersichtlichkeit halber eine kleine Hilfsfunktion, an die wir den Endpunkt und gegebenenfalls weitere URL-Parameter übergeben und eine URL nach dem obigen Format zurückbekommen:

/**
 * 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;
}

Und jetzt könnten wir uns beispielsweise die Produkt-Kategorien und -Attribute wie folgt holen:

// 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 );

Um zum Beispiel mehrere Produkte anzulegen, könnten Daten von anzulegenden Produkten in einer Schleife durchlaufen werden und dabei ein temporäres Array mit den Request-Daten gefüllt werden, das dann in etwa so aussieht:

$tmp_requests_array[] = [
	'url'     => build_api_url( "products" ),
	'type'    => 'POST',
	'data'    => $prod_data,
];

$prod_data ist dabei ein Array der Produktdaten, wie es aus meinem Artikel »WooCommerce-Produkt mit PHP über die REST-API hinzufügen«. Nachdem die Produkte durchlaufen wurden und das Array mit den Requests fertig ist, wird es an request_multiple() übergeben. Hier sollte eventuell nur darauf geachtet werden, nicht zu viele Anfragen gleichzeitig an den Server zu schicken.

Ein Punkt, der bei requests_multiple() aktuell neben der Deaktivierung der SSL-Prüfung ebenfalls noch nicht funktioniert ist die Übergabe von User und Passwort, um einen via .htaccess geschützten Shop anzusprechen.

Das könnte auch interessant sein

Schreib einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.