Recommended practices for configuring, running, and maintaining the .NET SDK.
Keep the SDK up to date
Always use a recent version of the SDK to ensure you have the latest features, performance improvements, and security fixes.
To stay informed about new releases, watch the GitHub repository or check NuGet Gallery for new versions.
Reuse the client
UseCommercetoolsApi and UseCommercetoolsImportApi register the client with the dependency injection container, so ASP.NET Core creates and reuses a single instance for the application's lifetime. Inject the registered client into your services and controllers instead of constructing one manually:public class ProductsService : IProductsService
{
private readonly ProjectApiRoot _api;
public ProductsService(ProjectApiRoot api)
{
_api = api;
}
}
Choose the lifetime of application services according to their state and dependencies. The injected SDK client remains reusable whether the consuming service is transient, scoped, or singleton.
Configure retries and timeouts
The SDK does not retry requests and does not configure its own timeout. Requests use the default
HttpClient timeout of 100 seconds, which is usually too long for interactive workloads. Add a Polly policy to the SDK's HttpClient to retry transient network errors and 5xx responses with exponential backoff, and to cancel requests that exceed a shorter timeout budget. For the full setup, see Configure retries and timeouts.Handle errors safely
The SDK throws
ApiHttpException for HTTP responses with a status code of 400 or higher. Its StatusCode property contains the response status code. Catch this exception in a global exception handler and map it to a sanitized response. Avoid returning the exception object directly, since it can expose internal request and response details to API consumers.using commercetools.Base.Client;
using Microsoft.AspNetCore.Diagnostics;
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var feature = context.Features.Get<IExceptionHandlerFeature>();
if (feature?.Error is ApiHttpException apiException)
{
context.Response.StatusCode = apiException.StatusCode;
await context.Response.WriteAsJsonAsync(new { message = "The commercetools API request failed." });
return;
}
context.Response.StatusCode = 500;
await context.Response.WriteAsJsonAsync(new { message = "An unexpected error occurred." });
});
});
Check whether a resource exists without fetching it
Use a
Head() request instead of Get() when you only need to know whether a resource exists. This avoids transferring and deserializing the full resource body:public async Task<bool> CheckProductExistsAsync(string key)
{
try
{
await _api.Products().WithKey(key).Head().ExecuteAsync();
return true;
}
catch (ApiHttpException ex) when (ex.StatusCode == 404)
{
return false;
}
}
Logging
The SDK logs every request and response through
Microsoft.Extensions.Logging. UseCommercetoolsApi registers a logging handler automatically, so no extra setup is required. Configure the log level for the commercetoolsLoggerHandler category in appsettings.json:{
"Logging": {
"LogLevel": {
"commercetoolsLoggerHandler": "Debug"
}
}
}
To customize logging behavior, implement
ILoggerHandlerFactory and register it after calling UseCommercetoolsApi, so your implementation replaces the default:services.UseCommercetoolsApi(configuration, "Client");
services.AddSingleton<ILoggerHandlerFactory, CustomLoggerHandlerFactory>();
Further resources
- Get started: client setup, multiple clients, and retry configuration
- Query Predicate builders: type-safe query predicates
- Integration tests: working examples for common SDK operations