bcquality/community/knowledge/web-services/api-enum-values-are-a-contract-by-name-not-ordinal.good.al
waldo 2439d5c412
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run
knowledge(web-services): under schema 2.0 an API enum field is a contract by member name, under 1.0 by caption (#149)
What an API page publishes for an enum field depends on the OData schema
version: member names under 2.0, the caption as Edm.String under 1.0, never
the ordinal. Custom APIs defaulted to 1.0 through BC 23 and to 2.0 from BC 24.
LLMs assert one carrier as universal and get one direction wrong.

Co-authored-by: waldo1001 <12088142+waldo1001@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-02 16:26:24 +02:00

54 lines
1.5 KiB
AL

// Neither the name CreditNote nor its caption changes in place: schema 2.0 consumers bind to the name,
// schema 1.0 consumers to the caption. A new kind is appended; a retired kind is obsoleted, never deleted.
enum 50120 "Document Kind Good"
{
Extensible = true;
value(0; Invoice) { Caption = 'Invoice'; }
value(1; Order) { Caption = 'Order'; }
value(2; CreditNote) { Caption = 'Credit Note'; }
value(3; ReturnOrder) { Caption = 'Return Order'; }
value(4; Quote) { Caption = 'Quote'; ObsoleteState = Pending; ObsoleteReason = 'Quotes moved to the quotes API.'; ObsoleteTag = '3.0'; }
}
table 50121 "Document Header Good"
{
DataClassification = CustomerContent;
fields
{
field(1; "No."; Code[20]) { DataClassification = CustomerContent; }
field(2; Kind; Enum "Document Kind Good") { DataClassification = CustomerContent; }
}
keys
{
key(PK; "No.") { Clustered = true; }
}
}
page 50122 "Document API Good"
{
PageType = API;
APIPublisher = 'contoso';
APIGroup = 'documents';
APIVersion = 'v1.0';
EntityName = 'document';
EntitySetName = 'documents';
ODataKeyFields = SystemId;
SourceTable = "Document Header Good";
DelayedInsert = true;
layout
{
area(content)
{
repeater(records)
{
field(id; Rec.SystemId) { Caption = 'id'; Editable = false; }
field(number; Rec."No.") { Caption = 'number'; }
field(kind; Rec.Kind) { Caption = 'kind'; }
}
}
}
}