Declaimer: used gpt-5.6-sol to create this issue out of debugging session around API response sizes while working on fairpm/fair-plugin#525
Summary
The WordPress-compatible plugins/info/1.2 endpoint returns excessively large responses for action=query_plugins.
A standard Add Plugins Featured-tab request currently returns approximately 3.37 MB from AspireCloud, compared with approximately 86 KB from WordPress.org. This can cause FAIR Connect's Add Plugins request to exceed WordPress's 15-second HTTP timeout on some hosts.
Reproduction
Request:
GET /plugins/info/1.2/
?action=query_plugins
&request[page]=1
&request[per_page]=36
&request[locale]=en_US
&request[browse]=featured
&request[wp_version]=6.8
Example endpoints:
- AspireCloud:
https://api.aspirecloud.net/plugins/info/1.2/
- WordPress.org:
https://api.wordpress.org/plugins/info/1.2/
Observed results
Measurements taken using the same request parameters:
| API |
Plugins |
Response body |
| WordPress.org |
8 |
85,831 characters |
| AspireCloud |
36 |
3,368,723 characters |
The AspireCloud response is approximately 39 times larger overall.
This is not explained only by the different result count. With per_page=8, AspireCloud returns approximately 710 KB, still about 8.3 times larger than the WordPress.org response containing 8 plugins.
Pagination also differs:
WordPress.org: page=1, pages=1, results=8
AspireCloud: page=1, pages=31, results=1089
Cause
QueryPluginsService currently maps every listing result to the full PluginResponse:
https://github.com/fairpm/aspirecloud/blob/main/app/Services/PluginServices/QueryPluginsService.php
PluginResponse::fromPlugin() includes both listing fields and fields intended for plugin_information:
https://github.com/fairpm/aspirecloud/blob/main/app/Values/WpOrg/Plugins/PluginResponse.php
Detail-only data included for every listing entry includes:
sections, including FAQ and review HTML
- Complete
versions maps
contributors
- Structured
screenshots
support_url
upgrade_notice
banners
- Repository and commercial-support metadata
- AspireCloud-specific metadata
Some plugins have hundreds of versions or large review and screenshot sections.
QueryPluginsRequest accepts fields, but QueryPluginsService does not apply it. Explicitly disabling versions, sections, screenshots, description, and contributors currently produces the same 3,368,723-character response.
The service also eagerly loads contributors for every listing result, even though WordPress.org does not include contributors in its default query_plugins response.
Expected behavior
query_plugins should return a compact listing representation comparable to WordPress.org.
Full plugin metadata should remain available through:
action=plugin_information
Explicit request[fields] values should also be honored.
Suggested implementation
-
Introduce a dedicated QueryPluginResponse DTO containing only the fields needed for plugin listings.
-
Continue using the existing full PluginResponse for plugin_information.
-
Change QueryPluginsService to map results to QueryPluginResponse rather than PluginResponse.
-
Normalize and apply QueryPluginsRequest::$fields, including associative values such as:
request[fields][description]=false
request[fields][versions]=false
The theme API's ThemeFields/withFields() implementation may provide a useful pattern.
-
Avoid eager-loading contributors for ordinary listing requests.
-
Review browse=featured. It currently matches more than 1,000 plugins using rating/origin criteria, whereas WordPress.org returns a small curated set. If AspireCloud intentionally defines its own Featured collection, it should still be bounded appropriately.
-
Ensure any response cache varies on request parameters, particularly fields, page, per_page, browse, locale, and WordPress version.
Tests
Add feature tests confirming that:
- Default
query_plugins responses omit detail-only fields such as versions, sections, contributors, screenshots, and banners.
plugin_information continues returning full details.
- Explicitly disabled fields are omitted.
per_page and pagination remain correct.
- The default listing response does not eagerly serialize full plugin metadata.
browse=featured returns the intended bounded collection.
Impact
This affects FAIR Connect's Add Plugins screen because it uses the standard WordPress query_plugins request with a 15-second timeout. Downloading and decoding a multi-megabyte response can result in http_request_failed/cURL timeout errors even when AspireCloud itself is reachable.
Declaimer: used gpt-5.6-sol to create this issue out of debugging session around API response sizes while working on fairpm/fair-plugin#525
Summary
The WordPress-compatible
plugins/info/1.2endpoint returns excessively large responses foraction=query_plugins.A standard Add Plugins Featured-tab request currently returns approximately 3.37 MB from AspireCloud, compared with approximately 86 KB from WordPress.org. This can cause FAIR Connect's Add Plugins request to exceed WordPress's 15-second HTTP timeout on some hosts.
Reproduction
Request:
Example endpoints:
https://api.aspirecloud.net/plugins/info/1.2/https://api.wordpress.org/plugins/info/1.2/Observed results
Measurements taken using the same request parameters:
The AspireCloud response is approximately 39 times larger overall.
This is not explained only by the different result count. With
per_page=8, AspireCloud returns approximately 710 KB, still about 8.3 times larger than the WordPress.org response containing 8 plugins.Pagination also differs:
Cause
QueryPluginsServicecurrently maps every listing result to the fullPluginResponse:https://github.com/fairpm/aspirecloud/blob/main/app/Services/PluginServices/QueryPluginsService.php
PluginResponse::fromPlugin()includes both listing fields and fields intended forplugin_information:https://github.com/fairpm/aspirecloud/blob/main/app/Values/WpOrg/Plugins/PluginResponse.php
Detail-only data included for every listing entry includes:
sections, including FAQ and review HTMLversionsmapscontributorsscreenshotssupport_urlupgrade_noticebannersSome plugins have hundreds of versions or large review and screenshot sections.
QueryPluginsRequestacceptsfields, butQueryPluginsServicedoes not apply it. Explicitly disablingversions,sections,screenshots,description, andcontributorscurrently produces the same 3,368,723-character response.The service also eagerly loads contributors for every listing result, even though WordPress.org does not include contributors in its default
query_pluginsresponse.Expected behavior
query_pluginsshould return a compact listing representation comparable to WordPress.org.Full plugin metadata should remain available through:
Explicit
request[fields]values should also be honored.Suggested implementation
Introduce a dedicated
QueryPluginResponseDTO containing only the fields needed for plugin listings.Continue using the existing full
PluginResponseforplugin_information.Change
QueryPluginsServiceto map results toQueryPluginResponserather thanPluginResponse.Normalize and apply
QueryPluginsRequest::$fields, including associative values such as:The theme API's
ThemeFields/withFields()implementation may provide a useful pattern.Avoid eager-loading
contributorsfor ordinary listing requests.Review
browse=featured. It currently matches more than 1,000 plugins using rating/origin criteria, whereas WordPress.org returns a small curated set. If AspireCloud intentionally defines its own Featured collection, it should still be bounded appropriately.Ensure any response cache varies on request parameters, particularly
fields,page,per_page,browse, locale, and WordPress version.Tests
Add feature tests confirming that:
query_pluginsresponses omit detail-only fields such asversions,sections,contributors,screenshots, andbanners.plugin_informationcontinues returning full details.per_pageand pagination remain correct.browse=featuredreturns the intended bounded collection.Impact
This affects FAIR Connect's Add Plugins screen because it uses the standard WordPress
query_pluginsrequest with a 15-second timeout. Downloading and decoding a multi-megabyte response can result inhttp_request_failed/cURL timeout errors even when AspireCloud itself is reachable.