The 2nd method - REST API client
Overview
- This is the second way of communication:
- The standard REST API calls of application domain services using HTTP methods
- Each backend service has REST API endpoints
- REST API is defined by OPEN API 3.0 standard
- Supported by 3rd-party tools like AutoRest, NSwag, editor.swagger.io etc
- The most common endpoints supported by C# Connector nuget package
- REST API is defined by OPEN API 3.0 standard
See more: OIDC/OAuth2 authentication

- Example - how to consume REST API:
- Use HTTP client to call API endpoint you have chosen
- See in example:
- Controllers/Examples12Controller.cs
Example2_GetOrders_Using_3rdPartySupportOnlyExample2_GetOrders_Using_StandardConnector
- Controllers/Examples12Controller.cs
Get orders using self-made connector based on Microsoft .NET and 3rd-party packages
- The demonstration example how to integrate with other backend service running on AVAplace
- Important: This code doesn't fully cover all requirements for more complex integration scenarios
- See in example:
- CustomConnectors/Example2_SelfMade3rdPartyBasedOrderClient.cs
- Controllers/Examples12Controller.cs
Example2_GetOrders_Using_3rdPartySupportOnly
Usage example:
private readonly IServiceProvider _serviceProvider;
private readonly SsoAuthOptions _authOptions;
private readonly Uri _authBaseUri;
private readonly Uri _apiBaseUri;
/// <summary>
/// Example of common rest api call against platform with manual token handling.
/// This example isn't recommended to be used in production environment, it's only for demonstration purposes.
/// The example uses particular endpoint of PlatformStore.Order domain which is well-known with partner's application.
/// </summary>
public async Task<string> GetOrdersAsync(string tenantId, string orderAccessType, int offset = 0, int limit = 100, CancellationToken ct = default)
{
if (string.IsNullOrEmpty(orderAccessType)) throw new ArgumentNullException(nameof(orderAccessType));
ct.ThrowIfCancellationRequested();
// *** 1. authenticate ***
//try get access token from "Authorization" header of HTTP request
var httpContextAccessor = _serviceProvider.GetService<IHttpContextAccessor>();
string headerValue = httpContextAccessor?.HttpContext?.Request?.Headers[HeaderNames.Authorization];
AuthenticationHeaderValue authHeader;
if (!string.IsNullOrEmpty(headerValue))
{
authHeader = AuthenticationHeaderValue.Parse(headerValue);
}
else
{
//create access token by IdentityProvider using clientId and clientSecret (OIDC)
var authClient = new HttpClient { BaseAddress = _authBaseUri };
// - get discovery document
var discoveryRequest = new DiscoveryDocumentRequest { Address = _authOptions.Authority };
var discoveryResponse = await authClient.GetDiscoveryDocumentAsync(discoveryRequest, cancellationToken: ct);
if (discoveryResponse.IsError)
{
throw new InvalidOperationException($"'{discoveryResponse.Error}' - '{discoveryResponse.ErrorType}'", discoveryResponse.Exception);
}
// - get access token using client credentials
var tokenRequest = new ClientCredentialsTokenRequest
{
Address = discoveryResponse.TokenEndpoint,
ClientId = _authOptions.ClientId,
ClientSecret = _authOptions.ClientSecret,
Scope = _authOptions.Audience
};
// - append requested tenantId (optional)
if (!string.IsNullOrEmpty(tenantId))
{
tokenRequest.Parameters.Add("tid", tenantId);
}
// - call REST API endpoint of ASOL.IdentityProvider service
var tokenResponse = await authClient.RequestClientCredentialsTokenAsync(tokenRequest, ct);
if (tokenResponse.IsError)
{
throw new InvalidOperationException($"'{tokenResponse.Error}' - '{tokenResponse.ErrorDescription}'", discoveryResponse.Exception);
}
authHeader = new AuthenticationHeaderValue(tokenResponse.TokenType, tokenResponse.AccessToken);
}
// *** 2. call endpoint ***
//call REST API endpoint of ASOL.PlatformStore.Order service
var resource = "api/v1/Order";
var apiClient = new FluentClient(_apiBaseUri);
var request = apiClient.GetAsync(resource)
.WithAuthentication(authHeader.Scheme, authHeader.Parameter)
.WithCancellationToken(ct)
.WithArgument("orderAccessType", orderAccessType)
.WithArgument("offset", offset)
.WithArgument("limit", limit);
//return CollectionResult<OrderModel> contract as serialized JSON string
var result = await request.AsString();
return result;
}
Get orders using standard connector using ASOL.PlatformStore.Order.Connector package
- The most comfortable way to integrate with other backend service running on AVAplace
- The most preferred way for production environment
- See in example:
- Controllers/Examples12Controller.cs
Example2_GetOrders_Using_StandardConnector
- Controllers/Examples12Controller.cs
Registration example (Startup.cs):
services.Configure<SsoAuthOptions>(configuration.GetSection(SsoAuthOptions.DefaultSectionName));
services.AddStandardApiTokenProviders();
services.Configure<PlatformStoreOrderClientOptions>(Configuration.GetSection(nameof(PlatformStoreOrderClientOptions)));
services.AddPlatformStoreOrderClient();
Usage example:
using ASOL.PlatformStore.Order.Connector;
//get client instance via dependency injection
var orderClient = _serviceProvider.GetRequiredService<IPlatformStoreOrderClient>();
//prepare query parameters
var orderFilter = new OrderFilter { OrderAccessType = OrderAccessType.Customer };
// *** 1. authenticate *** (already included in api call)
// *** 2. call endpoint ***
//get all orders via REST API client (using standard connector of ASOL.PlatformStore.Order service)
var ordersResult = await orderClient.GetOrdersAsync(orderFilter, default);