HttpHelper
Use HttpHelper to communicate with third-party services over HTTP from custom code. HttpHelper provides asynchronous methods to perform standard HTTP operations such as GET, POST, PUT, PATCH, and DELETE. It supports both generic (T) and raw HttpResponseMessage responses, giving you flexibility in handling external API responses. It also supports per-request customization using HttpRequestOptions, which allows you to pass additional headers dynamically for individual requests.
Best Practices
- Ensure the external endpoint is added to the Trusted-API configuration.
- Use retry logic to handle transient failures.
- Always set appropriate headers and request timeouts.
- Create the HttpHelper instance only once and reuse it across classes.
- Create the HttpHelper instance only in the main implementation class and pass it to other classes as needed.
- Use
HttpRequestOptionswhen headers need to vary per request. - Use certificate-based authentication for secure APIs when required.
Getting an Instance
ExternalApiAttributes class. This allows you to configure headers, retry logic, timeouts, and certificates.- Basic Usage: Use this option when you only need to specify the base URL of the external service.
ExternalApiAttributes externalApiAttributes = new("https://external-system-url"); var httpHelper = base.GetHttpHelper(externalApiAttributes);Use Case: Simple GET or POST requests without custom headers or retry logic.
- With Headers: Use this option when the external API requires custom headers such as authentication tokens.
Dictionary<string, string> headers = new() { /* define headers */ }; ExternalApiAttributes externalApiAttributes = new("https://external-system-url", headers); var httpHelper = base.GetHttpHelper(externalApiAttributes);Use case: APIs that require headers like
Authorization,Content-Type, or custom keys. - With Retry Options: Use this option to enable automatic retries for transient failures.
ExternalApiAttributes externalApiAttributes = new("https://external-system-url") { Retry = new Retry { IsEnabled = true, Count = 2 // Limit is 1–3 }, RequestTimeout = 10 }; var httpHelper = base.GetHttpHelper(externalApiAttributes);Use case: APIs that may fail intermittently due to network or rate-limiting issues.
- With Retry Disabled: Use this option when retrying requests is not recommended.
ExternalApiAttributes externalApiAttributes = new("https://external-system-url") { Retry = new Retry { IsEnabled = false }, RequestTimeout = 10 }; var httpHelper = base.GetHttpHelper(externalApiAttributes);Use case: APIs where retries could cause duplicate operations.
- With Certificate Info: Use this option when the external API requires client certificate authentication.
Dictionary<string, string> headers = new() { { "client_id", Config.ClientId }, { "client_secret", Config.ClientSecret } }; ExternalApiAttributes externalApiAttributes = new("https://apis.test.com", headers) { BaseUri = "https://apis.test.com", Certificates = new() { new CertificateInfo { RawData = Convert.FromBase64String(certString), Password = certPassword } }, Retry = new Retry { IsEnabled = false } }; var httpHelper = GetHttpHelper(externalApiAttributes);Use case: Secure APIs that require mutual TLS authentication.
Recommendation: Create the HttpHelper instance once in the main implementation class and pass it to other classes. HttpHelper instances cannot be created outside the main implementation class.
Reference
Method | Description |
|---|---|
Task<T>
GetAsync<T>(string requestUri) | Sends a GET request and deserializes the response into type T. |
Task<HttpResponseMessage>
GetAsync(string requestUri) | Sends a GET request and returns the raw HTTP response. |
Task<T>
GetAsync<T>(string requestUri, HttpRequestOptions options) | Sends a GET request with request options and deserializes the response. |
Task<HttpResponseMessage>
GetAsync(string requestUri, HttpRequestOptions options) | Sends a GET request with request options and returns the raw response. |
Method | Description |
|---|---|
Task<T>
PostAsync<T>(string requestUri, HttpContent content) | Sends a POST request and deserializes the response. |
Task<HttpResponseMessage>
PostAsync(string requestUri, HttpContent content) | Sends a POST request and returns the raw response. |
Task<T>
PostAsync<T>(string requestUri, HttpContent content, HttpRequestOptions
options) | Sends a POST request with request options and deserializes the response. |
Task<HttpResponseMessage>
PostAsync(string requestUri, HttpContent content, HttpRequestOptions options) | Sends a POST request with request options and returns the raw response. |
Method | Description |
|---|---|
Task<T>
PutAsync<T>(string requestUri, HttpContent content) | Sends a PUT request and deserializes the response. |
Task<HttpResponseMessage>
PutAsync(string requestUri, HttpContent content) | Sends a PUT request and returns the raw response. |
Task<T>
PutAsync<T>(string requestUri, HttpContent content, HttpRequestOptions
options) | Sends a PUT request with request options and deserializes the response. |
Task<HttpResponseMessage>
PutAsync(string requestUri, HttpContent content, HttpRequestOptions options) | Sends a PUT request with request options and returns the raw response. |
Method | Description |
|---|---|
Task<T>
PatchAsync<T>(string requestUri, HttpContent content) | Sends a PATCH request and deserializes the response. |
Task<HttpResponseMessage>
PatchAsync(string requestUri, HttpContent content) | Sends a PATCH request and returns the raw response. |
Task<T>
PatchAsync<T>(string requestUri, HttpContent content,
HttpRequestOptions options) | Sends a PATCH request with request options and deserializes the response. |
Task<HttpResponseMessage>
PatchAsync(string requestUri, HttpContent content, HttpRequestOptions
options) | Sends a PATCH request with request options and returns the raw response. |
Method | Description |
|---|---|
Task<HttpResponseMessage>
DeleteAsync(string requestUri) | Sends a DELETE request and returns the raw response. |
Task<HttpResponseMessage>
DeleteAsync(string requestUri, HttpContent content) | Sends a DELETE request with content and returns the raw response. |
Task<HttpResponseMessage>
DeleteAsync(string requestUri, HttpRequestOptions options) | Sends a DELETE request with request options and returns the raw response. |
Task<HttpResponseMessage>
DeleteAsync(string requestUri, HttpContent content, HttpRequestOptions
options) | Sends a DELETE request with request options and returns the raw response. |
Examples
The following examples demonstrate common scenarios for using HttpHelper in custom code. These examples are for reference only and illustrate how to configure HttpHelper, send HTTP requests, and handle responses when communicating with external services.
GET API Call
string baseAddress = "https://jsonplaceholder.typicode.com";
Dictionary<string, string> headers = new Dictionary<string, string>() { //define headers };
ExternalApiAttributes externalApiAttributes = new(baseAdderess, headers)
{
Retry = new Retry()
{
IsEnabled = false
},
RequestTimeout = 10
};
var httpHelper = GetHttpHelper(externalApiAttributes);
var logHelper = GetLogHelper();
string url = "/todos/1";
var response = await httpHelper.GetAsync<SampleResponse>(url);
logHelper.LogDebug(response);
Complete-GetAsync(https://jsonplaceholder.typicode.com/todos/1), HttpStatus=OK, Time=285.534
{"userId":1,"id":1,"title":"delectus aut autem","completed":false}
POST API Call
string baseAddress = "https://jsonplaceholder.typicode.com";
Dictionary<string, string> headers = new Dictionary<string, string>() { //define headers };
ExternalApiAttributes externalApiAttributes = new(baseAdderess, headers)
{
Retry = new Retry()
{
IsEnabled = true,
Count = 2
},
RequestTimeout = 20
};
var httpHelper = GetHttpHelper(externalApiAttributes);
var logHelper = GetLogHelper();
string url = "/todos/1";
var response = await httpHelper.GetAsync<SampleResponse>(url);
url = "/todos";
response.id = 0;
response.title = "Callback";
var contentToPost = new StringContent(JsonConvert.SerializeObject(response),Encoding.UTF8,"application/json");
var postResult = await httpHelper.PostAsync<SampleResponse>(url,contentToPost);
logHelper.LogDebug(postResult);
Complete-GetAsync(https://jsonplaceholder.typicode.com/todos/1), HttpStatus=OK, Time=285.534
{"userId":1,"id":1,"title":"delectus aut autem","completed":false}
Complete-PostAsync(https://jsonplaceholder.typicode.com/todos), HttpStatus=Created, Time=400.073
{"userId":1,"id":201,"title":"Callback","completed":false}
Passing Additional Headers Using HttpRequestOptions
HttpRequestOptions.
Use this approach when headers vary between requests and should not be configured globally while creating the HttpHelper instance.
using Conga.Platform.Extensibility.CustomCode.Library;
using Conga.Platform.Extensibility.CustomCode.Library.Models;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using CustomHttpRequestOptions = Conga.Platform.Extensibility.CustomCode.Library.Models.HttpRequestOptions;
namespace CustomApi.Template
{
public class SampleAccount : CodeExtensibility
{
public async Task<string> GetBadgeInfoAsync(CancellationToken cancellationToken)
{
ThrowIfCancellationRequested(cancellationToken);
string requestUri = "/MyBadge";
string baseRequestUri = "https://dummyjson.com";
ExternalApiAttributes externalApiAttributes = new ExternalApiAttributes(baseRequestUri);
Dictionary<string, string> additionalHeaders = new Dictionary<string, string>()
{
{"x-name", "Test" }
};
var httpHelper = base.GetHttpHelper(externalApiAttributes);
var response = await httpHelper.GetAsync(requestUri,
new CustomHttpRequestOptions()
{
AdditionalHeaders = additionalHeaders
});
return await response.Content.ReadAsStringAsync();
}
public async Task<string> PostExternalAsync(CancellationToken cancellationToken)
{
ThrowIfCancellationRequested(cancellationToken);
string requestUri = "https://dummyjson.com/products/add";
ExternalApiAttributes externalApiAttributes = new ExternalApiAttributes(requestUri);
var httpHelper = base.GetHttpHelper(externalApiAttributes);
Dictionary<string, string> data = new()
{
{"title", "BMW Pencil" },
{"description", "BMW Pencils" },
{"brand", "BMW" }
};
Dictionary<string, string> additionalHeaders = new Dictionary<string, string>()
{
{ "x-header", "sample-host" }
};
HttpContent httpContent = new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
var response = await httpHelper.PostAsync(requestUri, httpContent, new CustomHttpRequestOptions()
{
AdditionalHeaders = additionalHeaders
});
return await response.Content?.ReadAsStringAsync();
}
public async Task<string> PutExternalAsync(CancellationToken cancellationToken)
{
ThrowIfCancellationRequested(cancellationToken);
string requestUri = "https://dummyjson.com/products/1";
ExternalApiAttributes externalApiAttributes = new ExternalApiAttributes(requestUri);
var httpHelper = base.GetHttpHelper(externalApiAttributes);
Dictionary<string, string> data = new()
{
{"title", "BMW Pencil" },
{"description", "iPhone Galaxy +1" },
{"brand", "iPhone" }
};
Dictionary<string, string> additionalHeaders = new Dictionary<string, string>()
{
{ "x-host", "sample-host" }
};
HttpContent httpContent = new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
var response = await httpHelper.PutAsync(requestUri, httpContent, new CustomHttpRequestOptions()
{
AdditionalHeaders = additionalHeaders
});
return await response.Content?.ReadAsStringAsync();
}
public async Task<string> PatchExternalHttpContentAsync(CancellationToken cancellationToken)
{
ThrowIfCancellationRequested(cancellationToken);
string requestUri = "https://dummyjson.com/products/1";
ExternalApiAttributes externalApiAttributes = new ExternalApiAttributes(requestUri);
var httpHelper = base.GetHttpHelper(externalApiAttributes);
Dictionary<string, string> data = new()
{
{"description", "iPhone Galaxy latest" },
{"brand", "iPhone" }
};
Dictionary<string, string> additionalHeaders = new Dictionary<string, string>()
{
{ "x-test", "sample-host" }
};
HttpContent httpContent = new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8, "application/json");
var response = await httpHelper.PatchAsync(requestUri, httpContent, new CustomHttpRequestOptions()
{
AdditionalHeaders = additionalHeaders
});
return await response.Content?.ReadAsStringAsync();
}
public async Task<string> DeleteExternalAsync(CancellationToken cancellationToken)
{
ThrowIfCancellationRequested(cancellationToken);
string requestUri = "https://dummyjson.com/products/1";
ExternalApiAttributes externalApiAttributes = new ExternalApiAttributes(requestUri);
var httpHelper = base.GetHttpHelper(externalApiAttributes);
Dictionary<string, string> additionalHeaders = new Dictionary<string, string>()
{
{ "x-host", "sample-host" }
};
var response = await httpHelper.DeleteAsync(requestUri, new CustomHttpRequestOptions()
{
AdditionalHeaders = additionalHeaders
});
return await response.Content?.ReadAsStringAsync();
}
}
}
