bcquality/microsoft/knowledge/web-services/expose-operations-as-bound-actions.md
Jesper Schulz-Wedde 2b5550c346
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled
Improve partner onboarding and documentation navigation (#174)
Lead with a complete plugin quick start and add task-oriented usage, troubleshooting, customization, and contribution guides. Preserve the broader plugin framing, correct conflicting contract guidance, support Agents folder reviews, and align repository validation. Convert existing sample references to clickable links without changing knowledge rules.

Co-authored-by: Jesper Schulz-Wedde <jesper.schulzwedde@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-09-09 17:31:03 +02:00

2.3 KiB

bc-version domain keywords technologies countries application-area
all
web-services
api-page
serviceenabled
bound-action
webserviceactioncontext
setactionresponse
side-effect
patch
al
w1
all

Expose business operations as bound actions, not as writable status flags

Description

An API consumer that needs to do something to a record — post it, ship it, release it — should call an explicit operation, not mutate a field and hope a side effect fires. AL models this with a bound action: a [ServiceEnabled] procedure that takes var ActionContext: WebServiceActionContext, performs the work, and reports the result through the action context (typically a SetActionResponse helper that returns the affected record's id). The endpoint then exposes a callable action — .../salesOrders(<id>)/Microsoft.NAV.post — with a clear contract. The anti-pattern is to expose a writable Boolean or status field whose OnValidate quietly performs the operation: a routine PATCH that looks like a data edit silently triggers posting, with no discoverable action and surprising, hard-to-audit behaviour. LLMs reach for the flag-field approach because it is less code; this file is remedial because the platform-idiomatic, contract-safe choice (a bound action) is not the model's default.

Best Practice

Declare the operation as [ServiceEnabled] procedure Post(var ActionContext: WebServiceActionContext) on the API page. Inside, perform the operation against Rec, then call a SetActionResponse helper that writes the result — the bound record and its id — back into the WebServiceActionContext so the caller receives a well-formed response. The operation is now an explicit, named endpoint action separate from ordinary field writes.

See sample: expose-operations-as-bound-actions.good.al.

Anti Pattern

Exposing a writable Boolean (for example posted) whose OnValidate performs the posting. A client that PATCHes the field to true — an action indistinguishable from any other data edit — silently triggers a side-effecting business operation. The detection signal: an API page field whose OnValidate posts, ships, or releases, instead of a [ServiceEnabled] bound action.

See sample: expose-operations-as-bound-actions.bad.al.