Chapter 12: Integration with Other Systems
Objectives
By the end of this chapter you will be able to:
- Expose controlled extension functionality by publishing a codeunit as a web service
- Call external APIs with
HttpClientand handle the response status properly - Parse and validate integration payloads before changing any data
- Apply integration safeguards that support security and reliability
12.1 Exposing AL procedures as services
A codeunit can expose part of your extension’s functionality to external callers. Once the codeunit is published as a web service, each of its public procedures can be called as an OData V4 unbound action.
codeunit 50120 "Loan Integration API"
{
procedure GetInstallmentStatus(LoanNo: Code[20]; InstallmentNo: Integer): Text
var
Installment: Record "Loan Repayment Schedule";
begin
if not Installment.Get(LoanNo, InstallmentNo) then
Error('Installment %1/%2 was not found.', LoanNo, InstallmentNo);
if Installment.Paid then
exit('Paid');
exit('Open');
end;
}
To publish it, open the Web Services page in Business Central, add a line with object type Codeunit, object ID 50120, and a service name such as LoanIntegration, and select Published. An external system then calls the procedure with POST /ODataV4/LoanIntegration_GetInstallmentStatus, passing the parameters in the request body.
You don’t need an attribute on the procedure for this. The [ServiceEnabled] attribute is for a different case: a procedure on a page that is exposed as a web service, which becomes a bound action on that page’s records.
Return simple, stable values that external systems can depend on.
12.2 Calling external APIs safely
procedure GetCreditRiskScore(VendorNo: Code[20]): Decimal
var
Client: HttpClient;
Response: HttpResponseMessage;
Content: Text;
begin
Client.Get(StrSubstNo('https://api.example.com/vendors/%1/risk', VendorNo), Response);
if not Response.IsSuccessStatusCode then
Error('Risk API call failed with status %1.', Response.HttpStatusCode);
Response.Content.ReadAs(Content);
exit(EvaluateRiskScore(Content));
end;
Don’t show raw API responses to end users. Turn remote errors into clear messages that make sense in your business domain.
12.3 Payload validation and idempotency
Before you write external data to Business Central:
- Validate required keys and value formats.
- Reject unknown or unsupported status values.
- Prevent duplicate inserts for the same external transaction key.
These checks protect data consistency. They are also good targets for the tests you’ll write in Chapter 14.
12.4 Integration design practices
- Keep networking code in dedicated integration codeunits.
- Separate parsing and validation from persistence logic.
- Log enough context for support without leaking sensitive data.
- Set permissions and data classifications as described in Chapters 11 and 15.
Chapter summary
In this chapter you:
- Exposed controlled AL service operations
- Made outbound HTTP calls that handle failure explicitly
- Validated external payloads before changing data
- Applied integration design patterns that hold up in production
Tasks
- Service endpoint. Create a codeunit procedure that returns installment status, and publish the codeunit as a web service.
- HTTP robustness. Implement one outbound API call that checks
IsSuccessStatusCodeand handles failures. - Validation gate. Add payload validation that rejects missing or invalid required values.
- Try it yourself. Define how you would prevent the same external transaction from being imported twice.
Check your work: your integration flow should still honor table constraints from Chapter 7 and business-logic boundaries from Chapter 9.