Skip to content

Avoid loading the order collection twice for customer orders GraphQL query - #41086

Open
thai2301 wants to merge 3 commits into
magento:2.4-developfrom
thai2301:40966-graphql-duplicate-order-load
Open

Avoid loading the order collection twice for customer orders GraphQL query#41086
thai2301 wants to merge 3 commits into
magento:2.4-developfrom
thai2301:40966-graphql-duplicate-order-load

Conversation

@thai2301

@thai2301 thai2301 commented Aug 4, 2026

Copy link
Copy Markdown

Description

Fetching customer { orders { items { items } } } via GraphQL loads the sales order collection from the database twice:

  1. Magento\SalesGraphQl\Model\Resolver\CustomerOrders::resolve() loads the customer's orders (orderRepository->getList()) and passes each fully-loaded OrderInterface down as $value['model'].
  2. When the nested order items are resolved, Magento\SalesGraphQl\Model\OrderItem\DataProvider::fetchOrders() re-queries orderRepository->getList() for the very same orders, only to read each item's currency / store id / discount data.

The item resolvers already have the loaded parent order in hand, so there is no need to reload it. This adds an addOrder(OrderInterface $order) method to the data provider; the resolvers that own the order model (OrderItems, Invoice\InvoiceItems, CreditMemo\CreditMemoItems) register it, and fetchOrders() starts from those provided orders and queries the repository only for order ids that were not provided.

The Resolver\OrderItem path (nested child/bundle items, which only holds a parent order item, not the order) continues to work through that fallback, so behavior is unchanged for callers that don't provide an order. Keying is by sales_order.entity_id (the sales_order_item.order_id foreign key target), matching the previous lookup.

Related Issue

Fixes #40966

Manual testing scenarios

  1. Enable DB query logging.
  2. As a customer, run:
query {
    customer {
        orders {
            items {
                id
                items { id }
            }
        }
    }
}
  1. Before this change: the sales_order collection is loaded twice (once by CustomerOrders, once by OrderItem\DataProvider::fetchOrders).
  2. After this change: it is loaded once; the order-item data provider reuses the orders already loaded by the orders resolver. Invoice/credit-memo item queries are unaffected (they also reuse their already-loaded order), and nested child-item resolution still works via the not-provided fallback.

Questions or comments

None.

Contribution checklist

  • Pull request has a meaningful description of its purpose
  • All existing and new tests pass
  • Static tests pass
  • Ensured backward compatibility

Querying customer { orders { items { items } } } loaded the sales order
collection twice: once in CustomerOrders::resolve (for the orders list)
and again in OrderItem\DataProvider::fetchOrders(), which re-queried the
same orders to attach currency/store/discount data to each order item.

The item resolvers already hold the fully-loaded parent OrderInterface,
so they now hand it to the provider via a new addOrder() method, and
fetchOrders() reuses those, querying only the order ids that were not
provided. The Resolver\OrderItem (nested child items) path keeps working
through that fallback. Eliminates the duplicate order collection load.
@m2-assistant

m2-assistant Bot commented Aug 4, 2026

Copy link
Copy Markdown

Hi @thai2301. Thank you for your contribution!
Here are some useful tips on how you can test your changes using Magento test environment.
❗ Automated tests can be triggered manually with an appropriate comment:

  • @magento run all tests - run or re-run all required tests against the PR changes
  • @magento run <test-build(s)> - run or re-run specific test build(s)
    For example: @magento run Unit Tests

<test-build(s)> is a comma-separated list of build names.

Allowed build names are:
  1. Database Compare
  2. Functional Tests CE
  3. Functional Tests EE
  4. Functional Tests B2B
  5. Integration Tests
  6. Magento Health Index
  7. Sample Data Tests CE
  8. Sample Data Tests EE
  9. Sample Data Tests B2B
  10. Static Tests
  11. Unit Tests
  12. WebAPI Tests
  13. Semantic Version Checker

You can find more information about the builds here
ℹ️ Run only required test builds during development. Run all test builds before sending your pull request for review.


For more details, review the Code Contributions documentation.
Join Magento Community Engineering Slack and ask your questions in #github channel.

@thai2301

thai2301 commented Aug 4, 2026

Copy link
Copy Markdown
Author

@magento run all tests

getItemId() surfaces a DB value as a string and the provider passes it
to base64_encode(); the mock returned an int, tripping base64_encode()'s
string type in the new tests. Return it as a string, matching production.
@thai2301

thai2301 commented Aug 5, 2026

Copy link
Copy Markdown
Author

@magento run all tests

@thai2301

Copy link
Copy Markdown
Author

@magento run all tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Priority: P3 May be fixed according to the position in the backlog. Progress: pending review

Projects

Status: Pending Review

Development

Successfully merging this pull request may close these issues.

Graphql customer orders fetches the orders twice

2 participants