Commit 50dce6441b2 for woocommerce
commit 50dce6441b205fa12ad269305ce8986f6e5208ab
Author: Alba Rincón <albarin@users.noreply.github.com>
Date: Thu Apr 30 13:41:26 2026 +0200
Add configurable APQ caching toggle to GraphQL settings (#64448)
Co-authored-by: Nestor Soriano <konamiman@konamiman.com>
diff --git a/plugins/woocommerce/changelog/64448-64298-graphql-settings-apq b/plugins/woocommerce/changelog/64448-64298-graphql-settings-apq
new file mode 100644
index 00000000000..cddca349e54
--- /dev/null
+++ b/plugins/woocommerce/changelog/64448-64298-graphql-settings-apq
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add a setting to toggle Apollo Automatic Persisted Queries (APQ) caching on the GraphQL settings page.
\ No newline at end of file
diff --git a/plugins/woocommerce/src/Internal/Api/Main.php b/plugins/woocommerce/src/Internal/Api/Main.php
index 7ef7a9d76f3..ed369553577 100644
--- a/plugins/woocommerce/src/Internal/Api/Main.php
+++ b/plugins/woocommerce/src/Internal/Api/Main.php
@@ -27,6 +27,14 @@ class Main {
*/
public const OPTION_GET_ENDPOINT_ENABLED = 'woocommerce_graphql_get_endpoint_enabled';
+ /**
+ * Option name for the "Enable APQ caching" setting.
+ *
+ * When disabled, the persistedQuery extension is ignored and requests are
+ * treated as standard queries.
+ */
+ public const OPTION_APQ_ENABLED = 'woocommerce_graphql_apq_enabled';
+
/**
* Option name for the "Endpoint URL" setting.
*
@@ -77,6 +85,16 @@ class Main {
return wc_string_to_bool( get_option( self::OPTION_GET_ENDPOINT_ENABLED, 'yes' ) );
}
+ /**
+ * Whether the Apollo Automatic Persisted Queries (APQ) protocol is enabled.
+ *
+ * Defaults to true. When disabled, the `persistedQuery` request extension
+ * is ignored and requests are processed as standard (non-persisted) queries.
+ */
+ public static function is_apq_enabled(): bool {
+ return wc_string_to_bool( get_option( self::OPTION_APQ_ENABLED, 'yes' ) );
+ }
+
/**
* Whether the ObjectCache-backed query cache is enabled.
*
diff --git a/plugins/woocommerce/src/Internal/Api/QueryCache.php b/plugins/woocommerce/src/Internal/Api/QueryCache.php
index 5925afa17ad..99bac689c7c 100644
--- a/plugins/woocommerce/src/Internal/Api/QueryCache.php
+++ b/plugins/woocommerce/src/Internal/Api/QueryCache.php
@@ -50,10 +50,15 @@ class QueryCache {
* @return DocumentNode|array
*/
public function resolve( ?string $query, array $extensions ) {
- $apq = $extensions['persistedQuery'] ?? null;
-
- if ( is_array( $apq ) && 1 === ( $apq['version'] ?? null ) && ! empty( $apq['sha256Hash'] ) ) {
- return $this->resolve_apq( $query, $apq['sha256Hash'] );
+ $apq = $extensions['persistedQuery'] ?? null;
+ $apq_hash = is_array( $apq ) ? ( $apq['sha256Hash'] ?? null ) : null;
+
+ if ( Main::is_apq_enabled()
+ && is_array( $apq )
+ && 1 === ( $apq['version'] ?? null )
+ && is_string( $apq_hash )
+ && '' !== $apq_hash ) {
+ return $this->resolve_apq( $query, $apq_hash );
}
// Standard query — no APQ.
diff --git a/plugins/woocommerce/src/Internal/Api/Settings.php b/plugins/woocommerce/src/Internal/Api/Settings.php
index c642a9d519f..42dae14bfc8 100644
--- a/plugins/woocommerce/src/Internal/Api/Settings.php
+++ b/plugins/woocommerce/src/Internal/Api/Settings.php
@@ -70,6 +70,13 @@ class Settings {
'default' => 'yes',
'type' => 'checkbox',
),
+ array(
+ 'title' => __( 'Enable APQ caching', 'woocommerce' ),
+ 'desc' => __( 'Cache parsed queries using the Apollo Automatic Persisted Queries protocol', 'woocommerce' ),
+ 'id' => Main::OPTION_APQ_ENABLED,
+ 'default' => 'yes',
+ 'type' => 'checkbox',
+ ),
array(
'title' => __( 'Maximum query depth', 'woocommerce' ),
'desc' => __( 'Reject queries whose selection nesting exceeds this depth.', 'woocommerce' ),
diff --git a/plugins/woocommerce/tests/php/src/Internal/Api/SettingsTest.php b/plugins/woocommerce/tests/php/src/Internal/Api/SettingsTest.php
index 5968c021f40..7cc7540d516 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Api/SettingsTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Api/SettingsTest.php
@@ -95,6 +95,22 @@ class SettingsTest extends WC_Unit_Test_Case {
$this->assertSame( 'yes', $by_id[ Main::OPTION_GET_ENDPOINT_ENABLED ]['default'] );
}
+ /**
+ * @testdox add_settings defines the APQ checkbox with a 'yes' default (PHP 8.1+).
+ */
+ public function test_add_settings_defines_apq_checkbox(): void {
+ if ( PHP_VERSION_ID < 80100 ) {
+ $this->markTestSkipped( 'GraphQL settings require PHP 8.1+.' );
+ }
+
+ $fields = $this->sut->add_settings( array(), Settings::SECTION_ID );
+ $by_id = array_column( $fields, null, 'id' );
+
+ $this->assertArrayHasKey( Main::OPTION_APQ_ENABLED, $by_id );
+ $this->assertSame( 'checkbox', $by_id[ Main::OPTION_APQ_ENABLED ]['type'] );
+ $this->assertSame( 'yes', $by_id[ Main::OPTION_APQ_ENABLED ]['default'] );
+ }
+
/**
* @testdox add_settings defines the endpoint URL text field with the default constant as default.
*/