Rest Client requires an Http Client Handler implementation
Codeunit "Rest Client" does not send requests itself. It passes every request to an implementation of the "Http Client Handler" interface. When no handler is given, it uses the System Application’s own "Http Client Handler" codeunit, which calls HttpClient.Send. The outgoing call then belongs to the System Application, not to the app that built the request.
In a sandbox, allowing HTTP client requests for the System Application therefore allows them for every extension that uses the Rest Client. The outgoing web service request telemetry for those calls goes to Microsoft’s telemetry instead of the app publisher’s. Tests cannot substitute a response either, because the handler is the point where a test replaces the real call. Implement "Http Client Handler" in the app and pass it to the Rest Client.
Example
codeunit 50100 "Exchange Rate Sync" // Rest Client requires an Http Client Handler implementation [AC0033]
{
procedure GetRates(CurrencyCode: Code[10]): JsonToken
var
RestClient: Codeunit "Rest Client";
begin
exit(RestClient.GetAsJson('https://api.example.com/rates/' + CurrencyCode));
end;
}Add a codeunit that implements "Http Client Handler" and pass it to RestClient.Initialize:
codeunit 50110 "Exchange Rate Http Handler" implements "Http Client Handler"
{
Access = Internal;
procedure Send(CurrHttpClientInstance: HttpClient; HttpRequestMessage: Codeunit "Http Request Message"; var HttpResponseMessage: Codeunit "Http Response Message") Success: Boolean;
var
ResponseMessage: HttpResponseMessage;
begin
Success := CurrHttpClientInstance.Send(HttpRequestMessage.GetHttpRequestMessage(), ResponseMessage);
HttpResponseMessage := HttpResponseMessage.Create(ResponseMessage);
end;
}
codeunit 50100 "Exchange Rate Sync"
{
procedure GetRates(CurrencyCode: Code[10]): JsonToken
var
RestClient: Codeunit "Rest Client";
HttpHandler: Codeunit "Exchange Rate Http Handler";
begin
RestClient.Initialize(HttpHandler);
exit(RestClient.GetAsJson('https://api.example.com/rates/' + CurrencyCode));
end;
}RestClient.Create(HttpHandler) is equivalent. It returns the initialized Rest Client, which suits code that assigns the client in one statement:
RestClient := RestClient.Create(HttpHandler);Initialize(), Initialize(HttpAuthentication), Create() and Create(HttpAuthentication) all use the default handler, and so does a Rest Client that is used without being initialized. AC0033 only checks that the app contains a handler implementation. It does not check that each Rest Client receives it.
When the diagnostic is reported
- An object declares a global variable, local variable, parameter or return value of type
Codeunit "Rest Client". Locals in triggers of fields, actions, controls, report data items and XMLport elements count. - No codeunit in the same app implements
"Http Client Handler". - The Rest Client codeunit is matched on both its ID (2350) and its name.
- One diagnostic is reported per object, on the object name, regardless of how many Rest Client variables the object declares.
Exception
Test codeunits (Subtype = Test or TestRunner) and obsolete objects are not reported.
Only codeunits in the app being compiled count as an implementation. When the handler lives in a dependency app from the same publisher, such as a shared foundation app, the calls are still attributed to that publisher, but AC0033 does not see the handler. Suppress the diagnostic on the object:
// The "Http Client Handler" implementation is provided by the foundation app,
// a dependency from the same publisher; AC0033 only sees codeunits in this app.
#pragma warning disable AC0033
codeunit 50100 "Exchange Rate Sync"
#pragma warning restore AC0033
{
procedure GetRates(CurrencyCode: Code[10]): JsonToken
var
RestClient: Codeunit "Rest Client";
FoundationHttpHandler: Codeunit "Foundation Http Handler";
begin
RestClient.Initialize(FoundationHttpHandler);
exit(RestClient.GetAsJson('https://api.example.com/rates/' + CurrencyCode));
end;
}For an app that relies on a shared handler throughout, disable the rule in the ruleset instead.
AC0034
applies the same check to Codeunit Telemetry and Codeunit "Feature Telemetry".
See also
- Codeunit “Rest Client” on Microsoft Learn
- Interface “Http Client Handler” on Microsoft Learn
- Prefer the Rest Client module over the native HttpClient on GitHub Discussions