From 53d11403dd442d7ebf598f9440be066139f753fb Mon Sep 17 00:00:00 2001 From: Jeffrey Bulanadi Date: Mon, 15 Jun 2026 08:14:58 +0800 Subject: [PATCH] Add knowledge file for integration event parameter breaking change --- ...vent-parameter-is-a-breaking-change.bad.al | 29 +++++++++++++++ ...ent-parameter-is-a-breaking-change.good.al | 36 +++++++++++++++++++ ...on-event-parameter-is-a-breaking-change.md | 26 ++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 community/knowledge/events/integration-event-parameter-is-a-breaking-change.bad.al create mode 100644 community/knowledge/events/integration-event-parameter-is-a-breaking-change.good.al create mode 100644 community/knowledge/events/integration-event-parameter-is-a-breaking-change.md diff --git a/community/knowledge/events/integration-event-parameter-is-a-breaking-change.bad.al b/community/knowledge/events/integration-event-parameter-is-a-breaking-change.bad.al new file mode 100644 index 0000000..92c72e1 --- /dev/null +++ b/community/knowledge/events/integration-event-parameter-is-a-breaking-change.bad.al @@ -0,0 +1,29 @@ +// Demonstration only. Shows the wrong way: adding a parameter directly to an existing integration event. + +codeunit 50112 "Sales Post Events Bad" +{ + // BAD: ShipmentNo added directly to the existing event signature after subscribers already existed. + [IntegrationEvent(false, false)] + procedure OnAfterPostSalesOrder(var SalesHeader: Record "Sales Header"; ShipmentNo: Code[20]) + begin + end; + + procedure PostSalesOrder(var SalesHeader: Record "Sales Header"; ShipmentNo: Code[20]) + begin + // ... posting logic ... + OnAfterPostSalesOrder(SalesHeader, ShipmentNo); + end; +} + +codeunit 50113 "Existing Subscriber Bad" +{ + // COMPILE ERROR (AL0306): subscriber signature no longer matches the publisher. + // "The event subscriber method signature does not match the event publisher method signature." + // ShipmentNo was not on the original event. Every extension that subscribed breaks immediately - + // no deprecation period, no warning, no grace. The parameter change is a breaking change. + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales Post Events Bad", 'OnAfterPostSalesOrder', '', false, false)] + local procedure HandleAfterPostSalesOrder(var SalesHeader: Record "Sales Header") + begin + // This procedure no longer compiles after ShipmentNo was added to the publisher. + end; +} diff --git a/community/knowledge/events/integration-event-parameter-is-a-breaking-change.good.al b/community/knowledge/events/integration-event-parameter-is-a-breaking-change.good.al new file mode 100644 index 0000000..c8c8a35 --- /dev/null +++ b/community/knowledge/events/integration-event-parameter-is-a-breaking-change.good.al @@ -0,0 +1,36 @@ +// Demonstration only. Shows the correct way to extend an integration event that already has subscribers. + +codeunit 50110 "Sales Post Events" +{ + // Original event kept and marked obsolete so existing subscribers continue to compile. + [Obsolete('Use OnAfterPostSalesOrderWithShipmentNo instead.', '26.0')] + [IntegrationEvent(false, false)] + procedure OnAfterPostSalesOrder(var SalesHeader: Record "Sales Header") + begin + end; + + // New overload carries the extra parameter - existing subscribers on the old event still compile. + [IntegrationEvent(false, false)] + procedure OnAfterPostSalesOrderWithShipmentNo(var SalesHeader: Record "Sales Header"; ShipmentNo: Code[20]) + begin + end; + + procedure PostSalesOrder(var SalesHeader: Record "Sales Header"; ShipmentNo: Code[20]) + begin + // ... posting logic ... + OnAfterPostSalesOrder(SalesHeader); // kept for backward compat + OnAfterPostSalesOrderWithShipmentNo(SalesHeader, ShipmentNo); // new callers migrate here + end; +} + +codeunit 50111 "Shipment Notifier Subscriber" +{ + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales Post Events", 'OnAfterPostSalesOrderWithShipmentNo', '', false, false)] + local procedure HandleAfterPostSalesOrderWithShipmentNo(var SalesHeader: Record "Sales Header"; ShipmentNo: Code[20]) + begin + // Subscriber uses the new event; ShipmentNo is available without breaking old subscribers. + if ShipmentNo = '' then + exit; + // ... notify warehouse of shipment ... + end; +} diff --git a/community/knowledge/events/integration-event-parameter-is-a-breaking-change.md b/community/knowledge/events/integration-event-parameter-is-a-breaking-change.md new file mode 100644 index 0000000..1d64783 --- /dev/null +++ b/community/knowledge/events/integration-event-parameter-is-a-breaking-change.md @@ -0,0 +1,26 @@ +--- +bc-version: [all] +domain: events +keywords: [integration-event, publisher, subscriber, breaking-change, parameter, obsolete] +technologies: [al] +countries: [w1] +application-area: [all] +--- + +# Adding a parameter to an existing integration event is a breaking change + +## Description + +Every codeunit that subscribes to an `[IntegrationEvent]` must match the publisher's exact parameter signature. Adding a parameter to an existing event immediately breaks every subscriber — they fail to compile the moment the parameter is added to the publisher. This affects all consumers of the event, including those in other extensions the author does not control. + +## Best Practice + +Add a new event with the extended signature alongside the original. Keep the original event and mark it `[Obsolete(...)]` so existing subscribers continue to compile and authors have time to migrate. The new event name should reflect the addition (for example, append `WithShipmentNo` or increment a suffix). Raise both events during the transition period. + +See sample: `integration-event-parameter-is-a-breaking-change.good.al`. + +## Anti Pattern + +Adding a new parameter directly to the existing `[IntegrationEvent]` declaration. Every subscriber codeunit, in every extension that subscribed to that event, stops compiling immediately. There is no safe rollout path once the breaking signature is published. + +See sample: `integration-event-parameter-is-a-breaking-change.bad.al`.