Microsoft Business Central, od wersji BC14, umożliwia korzystanie z Page'a typu API. Tego typu page pozwala w szybki sposób "wystawić" dane z Business Central na świat zewnętrzny. Omówię nieco "od końca" jak połączyć się z API, zaczynając od wyniku i przechodząc do opisu implementacji i użycia. Zostań ze mną 🙂
Wynik odpytania API page, który omówimy w tym wpisie pokazano poniżej. Jest to odpowiedź w formaci JSON.

Dla porównania dane w Business Central wyglądają następująco:

Jak zacząć:
W BC musimy zdefiniować i opublikować page. Poniżej kod źródłowy zaczerpnięty z dokumentacji Microsoft :
(źródło Developing a custom API - Business Central | Microsoft Learn)
page 50162 "API Car Brand"
{
PageType = API;
APIVersion = 'v2.0';
APIPublisher = 'Greg';
APIGroup = 'ATMS';
EntityCaption = 'CarBrand';
EntitySetCaption = 'CarBrands';
EntityName = 'carBrand';
EntitySetName = 'carBrands';
ODataKeyFields = SystemId;
SourceTable = "Car Brand";
Extensible = false;
DelayedInsert = true;
layout
{
area(content)
{
repeater(Group)
{
field(id; Rec.SystemId)
{
Caption = 'Id';
Editable = false;
}
field(name; Rec.Name)
{
Caption = 'Name';
}
field(description; Rec.Description)
{
Caption = 'Description';
}
field(country; Rec.Country)
{
Caption = 'Country';
}
part(carModels; "API Car Model")
{
Caption = 'Car Models';
EntityName = 'carModel';
EntitySetName = 'carModels';
SubPageLink = "Brand Id" = Field(SystemId);
}
}
}
}
}
Do tego musimy zdefiniować przykładową tabelę, którą będziemy odpytywać:
table 50160 "Car Brand"
{
DataClassification = CustomerContent;
Caption = 'Car Brand';
fields
{
field(1; Name; Text[100])
{
Caption = 'Name';
}
field(2; Description; Text[100])
{
Caption = 'Description';
}
field(3; "Country"; Text[100])
{
Caption = 'Country';
}
}
keys
{
key(PK; Name)
{
Clustered = true;
}
}
}
Oraz Page, który pozwoli nam dodać rekordy do tabeli:
page 50160 "Car Brand List"
{
ApplicationArea = All;
Caption = 'Car Brand List';
PageType = List;
SourceTable = "Car Brand";
UsageCategory = Lists;
layout
{
area(content)
{
repeater(General)
{
field(Name; Rec.Name)
{
ApplicationArea = All;
}
field(Description; Rec.Description)
{
ApplicationArea = All;
}
field(Country; Rec.Country)
{
ApplicationArea = All;
}
}
}
}
}
Po opublikowaniu rozszerzenia, możemy odpytać API poprzez Postman lub zwykłą przeglądarkę.
Modelowy URL:
http://nazwaKontenra:portOdata/nazwaInstancji/APIPublisher/APIGroup/companies(CompanyID)/EntitySetName
Tak wygląda mój URL:
http://bc27:7048/BC/api/Greg/ATMS/v2.0/companies(43e66b3d-cded-f011-9de5-6045bdaba172)/carBrands

Aby zbudować poprawne zapytanie musimy ustalić poszczególne elementy zapytania:
CopanyID - uzysykujemy poprzez zapytanie na URL:
http:/nazwaKontenera:portOdata/nazwaInstancji/versjaAPI/companies
w moim przypadku:
http://bc27:7048/BC/api/v2.0/companies
CompanyID odczytujemy z pola ID.

NazwaKontenera - nazwa użyta w podczas tworzenia kontenera. W Dockerze odczytujemy ją z kolumny Name

Nazwa instancji - domyślnie BC
Wersja API, EntitySetName, APIPublisher, APIGroup - określiliśmy ją w obiekcie, typu API Page
page 50162 "API Car Brand"
{
PageType = API;
APIVersion = 'v2.0';
APIPublisher = 'Greg';
APIGroup = 'ATMS';
EntitySetName = 'carBrands';
PortOData - domyślnie 7048. Można go odczytać korzystając z polecenia
[BC27] PS C:\Run> Get-NAVServerConfiguration -serverInstance BC -KeyName ODataServicesPort
7048
Zazwyczaj port 7048 kontenera jest otwarty od momentu utworzenia kontenera, co można zweryfikować wykonując polecenie:
docker ps

Wpis powstał bez użycia AI, stąd może odbiegać od kanonów piękna dzisiejszych wpisów, ale staram się być naturalny. 🙂