Skip to content

APIV2: replace LoadFields with AddLoadFields#29955

Closed
jeffreybulanadi wants to merge 2 commits into
microsoft:mainfrom
jeffreybulanadi:fix/29634-apiv2-loadfields-to-addloadfields
Closed

APIV2: replace LoadFields with AddLoadFields#29955
jeffreybulanadi wants to merge 2 commits into
microsoft:mainfrom
jeffreybulanadi:fix/29634-apiv2-loadfields-to-addloadfields

Conversation

@jeffreybulanadi
Copy link
Copy Markdown

@jeffreybulanadi jeffreybulanadi commented Apr 21, 2026

Summary

APIV2 pages call Rec.LoadFields(...) inside SetCalculatedFields and LoadCurrencyInformation procedures, which are themselves called from OnAfterGetRecord. This causes a JIT (Just-In-Time) read from the database for every record fetched, resulting in telemetry errors under concurrent API load as reported in issue #29634.

Root Cause

Rec.LoadFields in OnAfterGetRecord forces a supplemental DB read per record. When many records are fetched concurrently the platform logs JIT load warnings and the performance degrades unnecessarily.

Fix

Replace Rec.LoadFields with Rec.AddLoadFields placed in OnOpenPage. AddLoadFields declares which fields must be included in the initial record-set query for the entire page session. The fields are fetched once alongside the primary key columns, removing the per-record JIT reads entirely.

Changes per page:

  • APIV2SalesInvoices - fields No., Currency Code, Amount Including VAT, Posted, Status
  • APIV2SalesCreditMemos - fields Applies-to Doc. Type, Currency Code
  • APIV2SalesQuotes - field Currency Code
  • APIV2PurchaseInvoices - field Currency Code
  • APIV2PurchaseCreditMemos - fields Applies-to Doc. Type, Currency Code
  • APIV2BankAccounts - field Currency Code (new OnOpenPage trigger added)

There is no behavioral change. The same fields are loaded; only the loading strategy changes from JIT per-record to eager per-session.

Fixes #29634

Fixes AB#632881

Replace per-record Rec.LoadFields calls inside SetCalculatedFields and
LoadCurrencyInformation procedures with Rec.AddLoadFields in OnOpenPage.

LoadFields invoked from OnAfterGetRecord causes JIT reads on every
record fetch, which triggers telemetry errors under concurrent load.
AddLoadFields declared in OnOpenPage ensures the required fields are
included in the initial dataset query, eliminating unnecessary JIT
round-trips entirely.

Affected pages:
- APIV2SalesInvoices: fields No., Currency Code, Amount Including VAT, Posted, Status
- APIV2SalesCreditMemos: fields Applies-to Doc. Type, Currency Code
- APIV2SalesQuotes: field Currency Code
- APIV2PurchaseInvoices: field Currency Code
- APIV2PurchaseCreditMemos: fields Applies-to Doc. Type, Currency Code
- APIV2BankAccounts: field Currency Code (new OnOpenPage trigger added)

Fixes microsoft#29634
@jeffreybulanadi jeffreybulanadi requested a review from a team as a code owner April 21, 2026 09:02
@JesperSchulz JesperSchulz added Integration GitHub request for Integration area linked Issue is linked to a Azure Boards work item labels Apr 24, 2026

trigger OnOpenPage()
begin
Rec.AddLoadFields("Currency Code");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We had issues with this kind of approach in the past. API page does not behave 100% as the actual page. In some cases the platform would open and close the page. Many properties that would be set from the OnOpen page would be lost. I'm not sure if we still have this kind of behavior on e.g. delete, POST, get $batch and other operations that can be done.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We would need an extensive testing before we uptake this change to address the risk.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good point. The BankAccounts page is different from the others in this PR because OnOpenPage was newly added just for AddLoadFields - there was no pre-existing OnOpenPage. This means that for API operations that may not trigger OnOpenPage (POST via OnInsertRecord, PATCH via OnModifyRecord, batch requests), AddLoadFields would not fire and LoadCurrencyInformation would fall back to a JIT read.

Switched OnOpenPage to OnInit for the BankAccounts page. OnInit fires when the page object is instantiated, before any trigger or data operation runs, making it the correct placement for AddLoadFields when there is no pre-existing OnOpenPage.

For the other pages in this PR (SalesInvoices, SalesCreditMemos, SalesQuotes, PurchaseInvoices, PurchaseCreditMemos), OnOpenPage already existed for permission checks. Adding AddLoadFields alongside those existing calls carries the same risk profile as the permission checks themselves, which are already relied on in production.

Regarding extensive testing - agreed. This change can be tested with API requests for GET (list and single), POST, PATCH, and DELETE on the Bank Accounts endpoint to confirm Currency Code is always correctly returned.

Copy link
Copy Markdown
Contributor

@nikolakukrika nikolakukrika May 11, 2026

Choose a reason for hiding this comment

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

We decided to skip this optimization for the time being to limit the risk.

Copy link
Copy Markdown
Contributor

@nikolakukrika nikolakukrika left a comment

Choose a reason for hiding this comment

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

left comments

OnOpenPage is not guaranteed to be called for all API page operations
(POST, PATCH, DELETE, batch). OnInit is always called when the page
object is instantiated, making it the correct trigger for AddLoadFields
which must fire before any record data is fetched.
@jeffreybulanadi jeffreybulanadi changed the title fix: Replace LoadFields with AddLoadFields in APIV2 pages APIV2: replace LoadFields with AddLoadFields Apr 30, 2026
@JesperSchulz
Copy link
Copy Markdown
Contributor

Thank you for your contribution and for taking the time to submit this pull request.

At this stage, we’re not able to accept the change. We’d like to revisit this proposal once the migration to BCApps is complete though. At that point, we’ll be in a better position to properly evaluate and validate changes like this.

We appreciate your contribution and encourage you to resubmit or revisit this after the transition has been finalized.

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

Labels

Integration GitHub request for Integration area linked Issue is linked to a Azure Boards work item

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: APIV2 LoadFields at OnAfterGetRecord leads to JIT Load Error in Telemetry

3 participants