Skip to content

Commit

Permalink
AL Rest Client (microsoft#24803)
Browse files Browse the repository at this point in the history
Provides functionality to easily call REST web services

The module contains methods to support
- Calling web services with just one line of code
- Creating request content from Text, JSON, XML or binary data
- Read the response as Text, JSON, XML or binary data
- Authenticate using basic authentication

Some examples:
```
// Getting text
ResponseText := ALRestClient.Get(Url).Content().AsText();

// Getting binary data
TempBlob := ALRestClient.Get(Url).Content().AsBlob();

// Posting binary data and returning binary data
ALHttpContent.Create(TempBlob)
TempBlob := ALRestClient.Post(Url, ALHttpContent).Content().AsBlob();

// Getting a JsonObject
JsonObject := ALRestClient.GetAsJson(Url).AsObject();

// Posting a JsonObject and returning the result as JsonObject
JsonObject := ALRestClient.PostAsJson(Url, JsonObject).AsObject();

// Using Basic Authentication
HttpAuthenticationBasic.Initialize('user01', 'Password123');
ALRestClient.Initialize(HttpAuthenticationBasic);
ALHttpResponseMessage := ALRestClient.Get('https://httpbin.org/basic-auth/user01/Password123');
```

Remarks:
- Support for OAuth can be added later. A module is already available,
but it requires some internal discussion.
- Telemetry signal RT0019 (Outgoing Web Service Request) will be lost
for the ISV because the platform only sends it to the app that uses
HttpClient directly. This needs to be addressed somehow.
- Documentation (like a readme.md file) can be generated from the XML
comments, but maybe it's better to write a more extensive document how
to use this new module.

---------

Co-authored-by: Jesper Schulz-Wedde <[email protected]>
  • Loading branch information
ajkauffmann and JesperSchulz authored Oct 6, 2023
1 parent a928470 commit a10bfe5
Show file tree
Hide file tree
Showing 22 changed files with 2,939 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .github/AL-Go-Settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@
"main"
],
"rulesetFile": "..\\Build\\Rulesets\\module.ruleset.json",
"PullRequestTrigger": "pull_request"
"PullRequestTrigger": "pull_request",
"alwaysBuildAllProjects": true
}
49 changes: 49 additions & 0 deletions Modules/System Tests/Rest Client/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"id": "ae153cbb-ad55-447c-9226-5af3ef57280f",
"name": "Rest Client Tests",
"publisher": "Microsoft",
"version": "23.0.0.0",
"brief": "Tests for the Rest Client module",
"description": "Tests for the Rest Client module",
"privacyStatement": "https://go.microsoft.com/fwlink/?LinkId=724009",
"EULA": "https://go.microsoft.com/fwlink/?linkid=2182906",
"help": "https://go.microsoft.com/fwlink/?linkid=2206603",
"url": "https://go.microsoft.com/fwlink/?LinkId=72401",
"dependencies": [
{
"id": "812b339d-a9db-4a6e-84e4-fe35cbef0c44",
"name": "Rest Client",
"publisher": "Microsoft",
"version": "23.0.0.0"
},
{
"id": "dd0be2ea-f733-4d65-bb34-a28f4624fb14",
"name": "Library Assert",
"publisher": "Microsoft",
"version": "23.0.0.0"
},
{
"id": "e31ad830-3d46-472e-afeb-1d3d35247943",
"name": "BLOB Storage",
"publisher": "Microsoft",
"version": "23.0.0.0"
}
],
"screenshots": [],
"platform": "23.0.0.0",
"target": "OnPrem",
"idRanges": [
{
"from": 134970,
"to": 134974
}
],
"resourceExposurePolicy": {
"allowDebugging": true,
"allowDownloadingSource": true,
"includeSourceInSymbolFile": true
},
"features": [
"NoImplicitWith"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

namespace System.Test.RestClient;

using System.RestClient;
using System.TestLibraries.Utilities;

codeunit 134973 "Http Authentication Tests"
{
Subtype = Test;

var
Assert: Codeunit "Library Assert";

[Test]
procedure TestAnonymousAuthentication()
var
HttpAuthenticationAnonymous: Codeunit "Http Authentication Anonymous";
begin
// [GIVEN] An anonymous authentication object

// [WHEN] The authentication object is asked if authentication is required
// [THEN] The authentication object should return false
Assert.IsFalse(HttpAuthenticationAnonymous.IsAuthenticationRequired(), 'Anonymous authentication should report that authentication is not required');

// [WHEN] The authentication object is asked to return the authorization header
// [THEN] The authentication object should return an empty list
Assert.AreEqual(HttpAuthenticationAnonymous.GetAuthorizationHeaders().Count, 0, 'Anonymous authentication should not return an authorization header');
end;

[NonDebuggable]
[Test]
procedure TestBasicAuthentication()
var
HttpAuthenticationBasic: Codeunit "Http Authentication Basic";
AuthHeader: Dictionary of [Text, SecretText];
BasicAuthHeaderValue: SecretText;
begin
// [GIVEN] A basic authentication object
HttpAuthenticationBasic.Initialize('USER01', SecretText.SecretStrSubstNo('Password123!'));

// [WHEN] The authentication object is asked if authentication is required
// [THEN] The authentication object should return true
Assert.IsTrue(HttpAuthenticationBasic.IsAuthenticationRequired(), 'Basic authentication should report that authentication is required');

// [WHEN] The authentication object is asked to return the authorization header
// [THEN] THe authentication object should return a dictionary with one element that is a base64 encoded string
AuthHeader := HttpAuthenticationBasic.GetAuthorizationHeaders();
Assert.AreEqual(AuthHeader.Count, 1, 'Basic authentication should return one authorization header');
Assert.AreEqual(AuthHeader.ContainsKey('Authorization'), true, 'Basic authentication should return an authorization header');

BasicAuthHeaderValue := AuthHeader.Get('Authorization');
Assert.AreEqual(BasicAuthHeaderValue.Unwrap(), 'Basic VVNFUjAxOlBhc3N3b3JkMTIzIQ==', 'Basic authentication should return a base64 encoded string');
end;
}
Loading

0 comments on commit a10bfe5

Please sign in to comment.