Performance: Prime product caches and add targetHints in REST API v4 orders#63654
Conversation
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>
Testing GuidelinesHi @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:
|
Test using WordPress PlaygroundThe changes in this pull request can be previewed and tested using a WordPress Playground instance. 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. |
📝 WalkthroughWalkthroughThis 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
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (2)
plugins/woocommerce/changelog/rest-api-v4-orders-cache-primingplugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/Controller.php
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>
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>
Product cache priming was split into PR #63654. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jorgeatorres
left a comment
There was a problem hiding this comment.
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.
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>
Product cache priming was split into PR #63654. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 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>
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:
targetHintson self links — Addsallowhints to theselflink in order responses so clients can determine permitted HTTP methods (GET/PUT/POST/PATCH/DELETE vs GET-only) without making an OPTIONS preflight request.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:
GETrequest to/wp-json/wc/v4/ordersas an admin user.targetHintsin the_links.selfobject withallow: ["GET", "PUT", "POST", "PATCH", "DELETE"].edit_shop_orderscapability.targetHintsshowsallow: ["GET"]only.Testing that has already taken place:
Code review and manual inspection. Changes are extracted directly from the tested PR #63440.
Milestone
Changelog entry