Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content

Performance: Prime product caches and add targetHints in REST API v4 orders#63654

Merged
mikejolley merged 1 commit intotrunkfrom
performance/rest-api-v4-product-cache-priming
Mar 13, 2026
Merged

Performance: Prime product caches and add targetHints in REST API v4 orders#63654
mikejolley merged 1 commit intotrunkfrom
performance/rest-api-v4-product-cache-priming

Conversation

@mikejolley
Copy link
Copy Markdown
Member

@mikejolley mikejolley commented Mar 12, 2026

Submission Review Guidelines:

Changes proposed in this Pull Request:

Extracted from #63440 for smaller review scope. This PR contains the REST API v4 Orders controller changes only:

  1. targetHints on self links — Adds allow hints to the self link in order responses so clients can determine permitted HTTP methods (GET/PUT/POST/PATCH/DELETE vs GET-only) without making an OPTIONS preflight request.

  2. Prime product caches in get_items() — Before serializing orders in a collection response, collects all product and variation IDs from line items and primes their post caches in a single batch call to _prime_post_caches(). This eliminates N+1 queries when resolving product data during order serialization.

How to test the changes in this Pull Request:

  1. Create several orders with product line items.
  2. Make a GET request to /wp-json/wc/v4/orders as an admin user.
  3. Verify the response includes targetHints in the _links.self object with allow: ["GET", "PUT", "POST", "PATCH", "DELETE"].
  4. Make the same request as a user without edit_shop_orders capability.
  5. Verify targetHints shows allow: ["GET"] only.
  6. Enable query logging (e.g. Query Monitor) and confirm product data is fetched in a single batch query rather than per-order.

Testing that has already taken place:

Code review and manual inspection. Changes are extracted directly from the tested PR #63440.

Milestone

Note: Check the box above to have the milestone automatically assigned when merged.
Alternatively (e.g. for point releases), manually assign the appropriate milestone.

Changelog entry

  • Automatically create a changelog entry from the details below.
  • This Pull Request does not require a changelog entry. (Comment required below)

Changelog entry was created manually.

Adds targetHints to self links so clients know allowed HTTP methods
without an OPTIONS request. Primes product post caches before order
serialization to avoid N+1 queries when resolving line item products.

Extracted from #63440 for smaller review scope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added the plugin: woocommerce Issues related to the WooCommerce Core plugin. label Mar 12, 2026
@woocommercebot woocommercebot requested review from a team and jorgeatorres and removed request for a team March 12, 2026 12:48
@github-actions
Copy link
Copy Markdown
Contributor

Testing Guidelines

Hi @jorgeatorres ,

Apart from reviewing the code changes, please make sure to review the testing instructions (Guide) and verify that relevant tests (E2E, Unit, Integration, etc.) have been added or updated as needed.

Reminder: PR reviewers are required to document testing performed. This includes:

  • 🖼️ Screenshots or screen recordings.
  • 📝 List of functionality tested / steps followed.
  • 🌐 Site details (environment attributes such as hosting type, plugins, theme, store size, store age, and relevant settings).
  • 🔍 Any analysis performed, such as assessing potential impacts on environment attributes and other plugins, conducting performance profiling, or using LLM/AI-based analysis.

⚠️ Within the testing details you provide, please ensure that no sensitive information (such as API keys, passwords, user data, etc.) is included in this public issue.

@mikejolley mikejolley self-assigned this Mar 12, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Test using WordPress Playground

The changes in this pull request can be previewed and tested using a WordPress Playground instance.
WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Test this pull request with WordPress Playground.

Note that this URL is valid for 30 days from when this comment was last updated. You can update it by closing/reopening the PR or pushing a new commit.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 12, 2026

📝 Walkthrough

Walkthrough

This pull request adds performance optimizations to the REST API v4 orders endpoint by introducing cache priming for products and adding targetHints metadata. These changes reduce N+1 queries during serialization by pre-fetching product caches and providing HTTP method hints in REST responses.

Changes

Cohort / File(s) Summary
Changelog Entry
plugins/woocommerce/changelog/rest-api-v4-orders-cache-priming
New changelog entry documenting the cache priming and targetHints performance improvement.
Orders Controller
plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/Controller.php
Added targetHints field to the self link in prepare_links conditionally allowing multiple HTTP methods based on user permissions. Implemented cache priming in get_items by collecting and deduplicating product/variation IDs from results, then calling _prime_post_caches to prevent N+1 queries.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarizes the main changes: priming product caches and adding targetHints to REST API v4 orders for performance improvement.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The PR description clearly outlines the two specific changes (targetHints and cache priming), explains the reasoning, and provides testing instructions aligned with the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch performance/rest-api-v4-product-cache-priming

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/Controller.php`:
- Around line 205-206: The targetHints.allow value currently uses a blanket
current_user_can('edit_shop_orders') check which may differ from per-method,
per-item permission checks; update the code that builds the response (the array
containing 'href' and 'targetHints') to compute allowed HTTP methods by calling
the same item-specific permission checks used by the route (e.g.,
wc_rest_check_post_permissions(...) or the equivalent per-method checks) for
each method (GET, PUT, POST, PATCH, DELETE) against $item (use $item->get_id())
and include only the methods that pass in targetHints.allow instead of the
single current_user_can call; ensure you call the same permission helper used by
the route so clients see the exact methods accepted for that specific item.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 60716585-9b92-471e-a197-61556a5df27c

📥 Commits

Reviewing files that changed from the base of the PR and between d24999a and 5c39456.

📒 Files selected for processing (2)
  • plugins/woocommerce/changelog/rest-api-v4-orders-cache-priming
  • plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/Controller.php

mikejolley added a commit that referenced this pull request Mar 12, 2026
Removes targetHints on self links and product cache priming from the
V4 Orders Controller — these are now in a separate PR for smaller
review scope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mikejolley added a commit that referenced this pull request Mar 12, 2026
Removes targetHints on self links and product cache priming from the
V4 Orders Controller — these are now in a separate PR for smaller
review scope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mikejolley added a commit that referenced this pull request Mar 12, 2026
Product cache priming was split into PR #63654.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@jorgeatorres jorgeatorres left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks @mikejolley!

Just noting that this doesn't fully remove N + 1 in the call chain: despite image_id being cached thanks to the priming here, OrderItemSchema::get_image() also calls wp_get_attachment_url() which queries the db for the attachment post and its metadata (so 2 queries per product). I don't think we can be certain that all possible N + 1's are covered, but might be something to look into next if needed.

@mikejolley mikejolley merged commit e637747 into trunk Mar 13, 2026
52 of 57 checks passed
@mikejolley mikejolley deleted the performance/rest-api-v4-product-cache-priming branch March 13, 2026 11:10
@github-actions github-actions Bot added this to the 10.7.0 milestone Mar 13, 2026
mikejolley added a commit that referenced this pull request Mar 18, 2026
Removes targetHints on self links and product cache priming from the
V4 Orders Controller — these are now in a separate PR for smaller
review scope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mikejolley added a commit that referenced this pull request Mar 18, 2026
Product cache priming was split into PR #63654.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mikejolley added a commit that referenced this pull request Mar 19, 2026
* Order Table Data Store - prime item caches

* API v4 - Prime product caches

* Prime order item meta data

* changelog

* Add targetHints for self to prevent extra permissions checks

* Simplify target hint checks

* Prime the needs_processing transient

* return type

* Add missing return type

* Move shared priming methods to abstract

* Fix type guard for post_type key

* Simplify type guards

* Update baseline

* Guard against non-refund objects in prime_refund_caches_for_orders

The woocommerce_hpos_pre_query filter can intercept nested
wc_get_orders calls, returning non-refund objects even when
type is shop_order_refund. Replace the type hint with an
instanceof guard to handle this gracefully.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Reviewed code, small improvements

* Simplify ID placeholders in queries

* Fix phpstan warnings

* Remove V4 controller changes split into PR #63654

Removes targetHints on self links and product cache priming from the
V4 Orders Controller — these are now in a separate PR for smaller
review scope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update changelog to remove product cache reference

Product cache priming was split into PR #63654.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Abstract refund total queries into shared base class

Move get_total_tax_refunded, get_total_shipping_tax_refunded, and
get_total_shipping_refunded from CPT and HPOS data stores into
Abstract_WC_Order_Data_Store_CPT. The only difference between the
two implementations was the refund orders JOIN clause, now provided
by an overridable get_refund_orders_join_clause() method.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Abstract prime_refund_total_caches_for_orders into shared base class

Move the refund total cache priming method from CPT and HPOS data
stores into Abstract_WC_Order_Data_Store_CPT. The tax query uses
overridable get_refund_orders_batch_join_clause() and
get_refund_parent_column() methods. The fundamentally different
refund totals query is handled by overridable get_batch_refund_totals().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add tests for HPOS order cache priming

Tests that prime_caches_for_orders correctly populates refund total,
tax refunded, and order item meta caches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Unify refund total methods into shared get_refunded_item_meta_total

Collapse get_total_tax_refunded, get_total_shipping_tax_refunded, and
get_total_shipping_refunded into thin wrappers around a single
get_refunded_item_meta_total() method parameterized by item type and
meta keys.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Address PR feedback: simplify array grouping and use prepared placeholders

Replace array_reduce with plain foreach loops for meta data grouping in
both abstract and CPT data stores. Use $wpdb->prepare with spread
operator for meta key IN clauses instead of esc_sql interpolation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Harden cache priming SQL and add CPT-path test coverage (#63705)

- Replace esc_sql() with $wpdb->prepare() and %d placeholders for
  order item ID queries in prime_order_item_caches_for_orders
- Change get_refund_orders_batch_join_clause() and get_batch_refund_totals()
  to accept array $order_ids instead of string $sanitized_ids, performing
  absint sanitization internally rather than trusting callers
- Add CPT data store tests for prime_caches_for_orders covering both
  refund total cache priming and order item meta priming

* Fix merge conflict

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Brandon Kraft <public@brandonkraft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin: woocommerce Issues related to the WooCommerce Core plugin.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants