API Library Template¶
The ConnectSoft API Library Template is a comprehensive framework for creating robust, reusable, and scalable service agent libraries in .NET Core. Designed for modern cloud-native and enterprise architectures, this template provides developers with all the tools needed to streamline the development of API integrations, ensure code quality, and adhere to industry best practices.
Overview¶
The API Library Template generates a production-ready foundation for building API service agent libraries that can be shared across projects, published as NuGet packages, and integrated into larger solutions. It follows Microsoft's .NET library design guidelines and incorporates best practices for HTTP client management, resiliency, authentication, and observability.
When to Use This Template¶
Use the API Library Template when:
- Creating service agent libraries for external API integrations
- Building SDKs for third-party services (e.g., Google Analytics, Stripe, AWS)
- Developing libraries for internal microservice communication
- Creating tenant-aware libraries for SaaS platforms
- Building libraries that require multiple authentication mechanisms
- Developing libraries that need advanced resiliency patterns
- Publishing API client libraries as NuGet packages with CI/CD automation
When to Use Library Template Instead¶
Use the Library Template when:
- Building general-purpose utility libraries without HTTP client needs
- Creating domain model or business logic libraries
- Developing libraries that don't interact with external APIs
- Building simple libraries without authentication or resiliency requirements
Key Features¶
Typed HTTP Client¶
- HttpClientFactory Integration: Optimized connection pooling, DNS updates, and lifecycle management
- Strongly-Typed Interfaces: Predictable API interactions with type safety
- Connection Pooling: Efficient resource management and reuse
- Proxy Support: Configurable web proxy for HTTP requests
Authentication Mechanisms¶
- None: Public APIs without authentication
- Basic Authentication: Username/password with Base64 encoding
- API Key: Header-based API key authentication
- OAuth2: Token-based authentication with client credentials flow
- OpenID Connect: Identity provider integration with token validation
Resiliency Patterns¶
- Standard Resilience Handler: Retry, circuit breaker, timeout, bulkhead, rate limiter
- Standard Hedging Handler: Parallel request execution for slow dependencies
- Polly Integration: Advanced resilience patterns via Polly.Core
- Chaos Injection: Fault and latency injection for testing resiliency
Metrics and Observability¶
- OpenTelemetry Metrics: Custom metrics implementation
- Request Tracking: Counters and histograms for API calls
- Failure Monitoring: Error tracking by status code
- Performance Metrics: Request duration and throughput
Testing Support¶
- Mock Server: WireMock.Net integration for API simulation
- Unit Tests: MSTest-based unit testing
- Integration Tests: End-to-end testing capabilities
- Chaos Testing: Resiliency validation under failure conditions
Generated Structure¶
The template generates a complete solution with the following structure:
YourApiLibraryName/
├── src/
│ └── YourApiLibraryName/
│ ├── I{ServiceName}Service.cs # Service interface
│ ├── {ServiceName}Service.cs # Service implementation
│ ├── {ServiceName}ServiceException.cs # Custom exception class
│ ├── {ServiceName}ServiceExtensions.cs # DI extension methods
│ ├── {ServiceName}Response.cs # Response DTO (example)
│ ├── {ServiceName}Result.cs # Result wrapper (example)
│ ├── {ServiceName}Error.cs # Error DTO (example)
│ ├── GlobalSuppressions.cs # Code analysis suppressions
│ ├── Options/
│ │ ├── {ServiceName}ServiceOptions.cs # Main options class
│ │ ├── Validate{ServiceName}ServiceOptions.cs # Options validator
│ │ ├── WebProxyOptions.cs # Proxy configuration
│ │ ├── ChaosInjectionOptions.cs # Chaos testing options
│ │ ├── BasicAuthenticationOptions.cs # (if Basic auth selected)
│ │ └── ApiKeyAuthenticationOptions.cs # (if ApiKey auth selected)
│ ├── Metrics/ # (if UseMetrics=true)
│ │ └── {ServiceName}ServiceMetrics.cs # Metrics implementation
│ └── {ServiceName}Service.xml # XML documentation
├── tests/
│ └── YourApiLibraryName.UnitTests/
│ ├── {ServiceName}ServiceUnitTests.cs # Standard unit tests
│ ├── {ServiceName}ServiceWithMockedServerUnitTests.cs # WireMock tests
│ ├── {ServiceName}ResultAssertionExtensions.cs # Test helpers
│ ├── Metrics/ # (if UseMetrics=true)
│ │ └── {ServiceName}ServiceMetricsUnitTests.cs
│ ├── appsettings.UnitTests.json # Test configuration
│ ├── appsettings.MockedServerUnitTests.json # Mock server config
│ ├── GlobalSuppressions.cs # Test suppressions
│ └── {ProjectName}.UnitTests.xml # Test XML docs
├── Docs/ # MkDocs documentation
│ ├── Index.md
│ ├── Overview.md
│ ├── GettingStarted.md
│ ├── Installation.md
│ ├── Configuration.md
│ ├── Authentication.md
│ ├── Features.md
│ ├── Testing.md
│ ├── API Reference.md
│ └── Roadmap.md
├── .template.config/ # Template metadata (excluded)
├── azure-pipelines.yml # CI/CD pipeline
├── azure-pipelines-template.yml # Pipeline template
├── Directory.build.props # Shared MSBuild properties
├── Directory.Packages.props # Central package management
├── ConnectSoft.ApiLibraryTemplate.nuspec # NuGet package spec
├── ConnectSoft.ApiLibraryTemplate.runsettings # Test run settings
├── mkdocs.yml # MkDocs configuration
├── nuget.config # NuGet feed configuration
├── YourApiLibraryName.slnx # Modern solution file
├── YourApiLibraryName.sln # Traditional solution file
└── README.md # Project README
Key Structure Details¶
Source Project Structure¶
- Service Files: Core service interface and implementation following the service agent pattern
- Options Folder: Contains strongly-typed configuration classes with validation
- Main options class includes resilience, proxy, and authentication settings
- Authentication options are conditionally included based on
AuthenticationType - Metrics Folder (conditional): Only included when
UseMetrics=true - Contains metrics implementation using
Microsoft.Extensions.Diagnostics - Tracks request counts, durations, and failures
Test Project Structure¶
- Unit Tests: Standard unit tests using MSTest framework
- Mocked Server Tests: Integration tests using WireMock.Net for API simulation
- Test Configuration: Separate
appsettingsfiles for different test scenarios - Metrics Tests (conditional): Only included when
UseMetrics=true
Documentation Structure¶
The template includes a complete MkDocs documentation structure with: - Getting started guides - Configuration documentation - Authentication setup guides - Feature documentation - API reference templates - Testing guides
Build and Configuration Files¶
- Directory.build.props: Shared MSBuild properties including code analyzers
- Directory.Packages.props: Central package version management
- azure-pipelines.yml: Ready-to-use CI/CD pipeline for Azure DevOps
- mkdocs.yml: Documentation site configuration
Template Parameters¶
| Parameter | Type | Required | Default | CLI Long Name | CLI Short Name | Description |
|---|---|---|---|---|---|---|
ApiServiceName |
string | Yes | ExchangeRate |
--api-service-name |
--api-srv-name |
Service name used in code (e.g., ExchangeRate). This value replaces ExchangeRate in file names and code. |
ApiServiceDescription |
string | Yes | Exchange rate |
--api-service-description |
--api-srv-desc |
A short human-readable description of the API being wrapped. |
AuthenticationType |
choice | No | None |
--authentication-type |
--auth-type |
Choose the type of authentication used by the target API. Options: None, Basic, OAuth, OpenIDConnect, ApiKey. |
UseMetrics |
bool | No | true |
--use-metrics |
--metrics |
Enable built-in metrics support for custom metrics. When false, the Metrics folder and related code are excluded. |
Framework |
choice | No | net8.0 |
--framework |
N/A | The target framework for the project. Options: net8.0, net9.0. |
buildDefinitionNumber |
string | No | "" (empty) |
--build-definition-number |
--bdn |
Custom Azure DevOps build definition number for CI/CD integration. Leave empty to use default. Replaces buildDefinitionNumber placeholder in README.md. |
CLI Usage¶
The template can be instantiated using the .NET CLI with various parameter formats. All parameters support both long names (kebab-case) and short names (aliases).
Basic Usage¶
dotnet new connectsoft-api-library \
--name ConnectSoft.GoogleAnalytics \
--api-service-name "GoogleAnalytics" \
--api-service-description "Google Analytics Measurement Protocol API" \
--authentication-type "ApiKey"
Using Short Names¶
dotnet new connectsoft-api-library \
--name ConnectSoft.GoogleAnalytics \
--api-srv-name "GoogleAnalytics" \
--api-srv-desc "Google Analytics Measurement Protocol API" \
--auth-type "ApiKey"
Framework Selection¶
# Target .NET 8.0 (default)
dotnet new connectsoft-api-library \
--name ConnectSoft.MyService \
--api-service-name "MyService" \
--api-service-description "My Service API" \
--framework net8.0
# Target .NET 9.0
dotnet new connectsoft-api-library \
--name ConnectSoft.MyService \
--api-service-name "MyService" \
--api-service-description "My Service API" \
--framework net9.0
With Azure DevOps Build Definition¶
dotnet new connectsoft-api-library \
--name ConnectSoft.MyService \
--api-service-name "MyService" \
--api-service-description "My Service API" \
--authentication-type "OAuth" \
--build-definition-number "123"
Disabling Metrics¶
dotnet new connectsoft-api-library \
--name ConnectSoft.MyService \
--api-service-name "MyService" \
--api-service-description "My Service API" \
--use-metrics false
Complete Example with All Parameters¶
dotnet new connectsoft-api-library \
--name ConnectSoft.StripeIntegration \
--api-service-name "Stripe" \
--api-service-description "Stripe Payment Processing API" \
--authentication-type "ApiKey" \
--use-metrics true \
--framework net9.0 \
--build-definition-number "456"
Template Symbols and Replacements¶
The template uses several mechanisms to customize the generated code based on your parameters.
Source Name Replacement¶
The template's source name ConnectSoft.ApiLibraryTemplate is automatically replaced with your project name (specified via --name parameter). This affects:
- Solution file names:
ConnectSoft.ApiLibraryTemplate.sln→YourProjectName.sln - Project folder names:
src/ConnectSoft.ApiLibraryTemplate/→src/YourProjectName/ - Namespace names throughout the codebase
- Assembly names and package references
Service Name Replacement¶
The service name placeholder ExchangeRate is replaced with your ApiServiceName parameter value. This affects:
- File names:
ExchangeRateService.cs→{ApiServiceName}Service.cs - Class names:
ExchangeRateService→{ApiServiceName}Service - Interface names:
IExchangeRateService→I{ApiServiceName}Service - Options class names:
ExchangeRateServiceOptions→{ApiServiceName}ServiceOptions - Extension method names:
AddExchangeRateService()→Add{ApiServiceName}Service() - Configuration section names:
ExchangeRateService→{ApiServiceName}Service - Comments and documentation: All references to "Exchange rate" are replaced with your
ApiServiceDescription
Generated Symbols¶
The template includes several generated symbols that are automatically replaced:
| Symbol | Type | Replacement Value | Purpose |
|---|---|---|---|
currentYear |
Generated | Current year (e.g., 2024) |
Copyright year in file headers |
IfDebug |
Generated | #if DEBUG |
Conditional compilation directive start |
ElseDirective |
Generated | #else |
Conditional compilation directive else |
EndIf |
Generated | #endif |
Conditional compilation directive end |
AuthoringMode |
Generated | false |
Used during template development to include all conditional code |
Computed Symbols¶
Computed symbols are derived from parameter values and control conditional compilation:
| Symbol | Condition | Purpose |
|---|---|---|
AuthenticationTypeNone |
AuthenticationType == "None" |
Controls authentication-related code |
UseBasicAuthenticationType |
AuthenticationType == "Basic" |
Includes BasicAuthenticationOptions.cs |
UseOAuthAuthenticationType |
AuthenticationType == "OAuth" |
Includes OAuth2 authentication code |
UseOpenIDConnectAuthenticationType |
AuthenticationType == "OpenIDConnect" |
Includes OpenID Connect authentication code |
UseApiKeyAuthenticationType |
AuthenticationType == "ApiKey" |
Includes ApiKeyAuthenticationOptions.cs |
These symbols are used in conditional compilation directives like #if UseMetrics and control which files are included in the generated project.
Conditional Features¶
The template uses conditional logic to include or exclude features based on your parameter selections. This ensures the generated code only contains what you need.
Authentication Type-Based File Exclusion¶
Based on the AuthenticationType parameter, specific authentication option files are excluded:
- When
AuthenticationType != "Basic":BasicAuthenticationOptions.csis excluded - When
AuthenticationType != "ApiKey":ApiKeyAuthenticationOptions.csis excluded - When
AuthenticationType == "None": All authentication option files are excluded - When
AuthenticationType == "OAuth"or"OpenIDConnect": OAuth2 authentication code is included viaConnectSoft.Extensions.Http.OAuth2package
Metrics Feature Conditional Inclusion¶
When UseMetrics is set to false:
- The entire
Metrics/folder is excluded from the source project - The
Metrics/folder is excluded from the test project - All metrics-related code is excluded via conditional compilation (
#if UseMetrics) - The
Microsoft.Extensions.Diagnosticspackage reference is excluded - Extension methods like
Add{ServiceName}Metrics()are not generated
When UseMetrics is true (default):
- Metrics classes are generated in
src/{ProjectName}/Metrics/ - Metrics unit tests are generated in
tests/{ProjectName}.UnitTests/Metrics/ - Service classes include metrics tracking code
- Metrics extension methods are available for dependency injection
Conditional Compilation Directives¶
The template uses C# preprocessor directives to conditionally compile code:
#if UseMetrics
using {ProjectName}.Metrics;
#endif
public class {ServiceName}Service
{
#if UseMetrics
private readonly {ServiceName}ServiceMetrics metrics;
#endif
public {ServiceName}Service(
HttpClient httpClient,
ILogger<{ServiceName}Service> logger,
#if UseMetrics
{ServiceName}ServiceMetrics metrics,
#endif
IOptions<{ServiceName}ServiceOptions> options)
{
// ...
}
}
Authoring Mode¶
The template includes an AuthoringMode symbol that is set to false by default. When developing or testing the template itself, you can enable AuthoringMode to include all conditional code paths simultaneously. This is useful for:
- Template development and testing
- Ensuring all code paths compile correctly
- Validating template structure
In AuthoringMode, all authentication types and metrics are included, allowing template authors to verify the complete template structure.
Solution Format Support¶
The template generates both modern .slnx (XML-based) and traditional .sln solution formats to ensure compatibility across different development environments.
Primary Format: .slnx¶
The template uses .slnx as the primary solution format. This modern XML-based format offers:
- Improved IDE Performance: Faster solution loading and better IntelliSense performance
- Better Build Performance: Faster builds with improved caching
- Modern Tooling: Better support in Visual Studio 2022 17.14+ and JetBrains Rider
Requirements for .slnx support: - .NET SDK 9.0.200 or later - Visual Studio 2022 17.14 or later (for full IDE support) - JetBrains Rider (current versions support .slnx)
Fallback Format: .sln¶
The template also generates a traditional .sln file for compatibility:
- Use when working with older IDEs or tools
- Required for VS Code (unless configured for .slnx)
- Compatible with all .NET SDK versions
- All functionality remains the same
IDE Support¶
| IDE | .slnx Support | .sln Support | Notes |
|---|---|---|---|
| Visual Studio 2022 17.14+ | ✅ Full | ✅ Full | Prefer .slnx for best performance |
| Visual Studio 2022 < 17.14 | ❌ No | ✅ Full | Use .sln file |
| JetBrains Rider | ✅ Full | ✅ Full | .slnx recommended |
| VS Code | ⚠️ Configurable | ✅ Full | Configure dotnet.defaultSolution setting |
VS Code Configuration¶
To use .slnx in VS Code, add this to your workspace settings:
Command Line Usage¶
Both solution formats work with standard .NET CLI commands:
# Restore packages
dotnet restore YourProjectName.slnx # or .sln
# Build solution
dotnet build YourProjectName.slnx -c Release
# Run tests
dotnet test YourProjectName.slnx --no-build
Configuration Options¶
The template implements the .NET Options pattern with comprehensive validation and strongly-typed configuration.
Options Pattern Implementation¶
The template generates a main options class {ServiceName}ServiceOptions that includes:
- Base URL: The API endpoint base address
- Default Timeout: Request timeout duration (1 second to 5 minutes)
- Web Proxy: Configurable proxy settings for HTTP requests
- Resilience Options: Configuration for retry, circuit breaker, and timeout strategies
- Standard Resilience Handler options
- Standard Hedging Handler options
- Chaos Injection: Options for fault and latency injection during testing
- Authentication Options: Type-specific authentication configuration (conditionally included)
Configuration Section Naming¶
The options class defines a constant for the configuration section name:
This means your appsettings.json should have a section named {ServiceName}Service:
{
"{ServiceName}Service": {
"BaseUrl": "https://api.example.com",
"DefaultTimeout": "00:00:30",
"EnableHttpStandardResilience": true,
"HttpStandardResilience": {
// Resilience configuration
},
"ApiKeyAuthentication": {
"ApiKey": "your-api-key",
"HeaderName": "X-API-Key"
}
}
}
Validation¶
The template implements comprehensive validation using:
- Data Annotations: Required fields, data types, and ranges are validated
- Custom Validator:
Validate{ServiceName}ServiceOptionsclass implementsIValidateOptions<T> - Startup Validation: Options are validated when the application starts via
ValidateOnStart() - Object Member Validation: Nested options are validated using
ValidateObjectMembers
Example validation attributes:
[Required]
[DataType(DataType.Url)]
required public string BaseUrl { get; set; }
[Required]
[Range(typeof(TimeSpan), "00:00:01", "00:05:00")]
required public TimeSpan DefaultTimeout { get; set; }
Service Registration Extension Methods¶
The template generates extension methods for easy dependency injection setup:
1. Add Options¶
This method:
- Binds configuration to the options class
- Validates data annotations
- Registers the custom validator
- Validates options at startup
- Throws OptionsValidationException if validation fails
2. Add Metrics (if UseMetrics=true)¶
This method: - Adds metrics infrastructure - Registers the metrics implementation as a singleton
3. Add Service¶
This method: - Registers the service as a typed HTTP client - Configures the HTTP client with base URL and timeout - Sets up authentication headers (based on authentication type) - Configures resilience handlers (if enabled) - Sets up chaos injection (if enabled) - Configures connection pooling and proxy settings
Important: You must call Add{ServiceName}Options() before Add{ServiceName}Service().
Complete Registration Example¶
// In Program.cs or Startup.cs
var builder = WebApplication.CreateBuilder(args);
// Step 1: Add and validate options
builder.Services.AddGoogleAnalyticsOptions(builder.Configuration);
// Step 2: Add metrics (if enabled)
builder.Services.AddGoogleAnalyticsMetrics();
// Step 3: Add the service
builder.Services.AddGoogleAnalyticsService();
var app = builder.Build();
Configuration Binding¶
The template uses BindConfiguration() with strict error handling:
This ensures that: - Unknown configuration keys cause errors (helping catch typos) - Configuration is strongly-typed - Type mismatches are caught early
Quick Start¶
Step 1: Create a New API Library¶
Create a new API library using the template with all recommended parameters:
dotnet new connectsoft-api-library \
--name ConnectSoft.GoogleAnalytics \
--api-service-name "GoogleAnalytics" \
--api-service-description "Google Analytics Measurement Protocol API" \
--authentication-type "ApiKey" \
--use-metrics true \
--framework net9.0 \
--build-definition-number "123"
Parameter explanations:
- --name: The project/solution name (replaces ConnectSoft.ApiLibraryTemplate)
- --api-service-name: Service name used in code (replaces ExchangeRate in file names and classes)
- --api-service-description: Human-readable description for documentation
- --authentication-type: Choose None, Basic, OAuth, OpenIDConnect, or ApiKey
- --use-metrics: Enable metrics support (set to false to exclude metrics)
- --framework: Target framework (net8.0 or net9.0)
- --build-definition-number: Azure DevOps build definition ID (optional, for CI/CD badges)
Step 2: Configure the Library¶
Update appsettings.json with your API configuration. The configuration section name matches your service name:
{
"GoogleAnalyticsService": {
"BaseUrl": "https://www.google-analytics.com",
"DefaultTimeout": "00:00:30",
"EnableHttpStandardResilience": true,
"HttpStandardResilience": {
"Retry": {
"MaxRetryAttempts": 3,
"BackoffType": "ExponentialWithJitter"
},
"CircuitBreaker": {
"FailureRatio": 0.5,
"MinimumThroughput": 10
}
},
"EnableHttpStandardHedgingResilience": false,
"EnableChaosInjection": false,
"WebProxy": {
"UseProxy": false
},
"ApiKeyAuthentication": {
"ApiKey": "your-api-key-here",
"HeaderName": "X-API-Key"
}
}
}
Step 3: Register Services¶
Register the service and options in your Program.cs or Startup.cs:
using ConnectSoft.GoogleAnalytics;
var builder = WebApplication.CreateBuilder(args);
// Step 1: Add and validate options (required first)
builder.Services.AddGoogleAnalyticsOptions(builder.Configuration);
// Step 2: Add metrics (if UseMetrics=true was used)
builder.Services.AddGoogleAnalyticsMetrics();
// Step 3: Add the service
builder.Services.AddGoogleAnalyticsService();
var app = builder.Build();
Important: Always call Add{ServiceName}Options() before Add{ServiceName}Service().
Step 4: Use the Service¶
Inject and use the service in your controllers or services:
using ConnectSoft.GoogleAnalytics;
public class AnalyticsController : ControllerBase
{
private readonly IGoogleAnalyticsService _service;
public AnalyticsController(IGoogleAnalyticsService service)
{
_service = service;
}
[HttpPost("track")]
public async Task<IActionResult> TrackEvent([FromBody] AnalyticsEvent evt)
{
var result = await _service.TrackEventAsync(evt);
if (result.IsSuccess)
{
return Ok(result);
}
return BadRequest(result.Error);
}
}
Alternative: Minimal Example¶
For a quick start with minimal configuration:
dotnet new connectsoft-api-library \
--name ConnectSoft.MyService \
--api-service-name "MyService" \
--api-service-description "My Service API"
This uses defaults:
- Authentication: None
- Metrics: true
- Framework: net8.0
- Build Definition: empty (uses default)
Architecture¶
Design Principles¶
- Service Agent Pattern: Encapsulates API interaction logic
- HttpClientFactory Pattern: Proper HTTP client lifecycle management
- Options Pattern: Strongly-typed, validated configuration
- Resilience First: Built-in fault tolerance mechanisms
- Observability: Comprehensive logging, metrics, and tracing support
Integration with AI Factory¶
The API Library Template is used by:
- API Library Generator Agent: Generates API library projects
- Backend Developer Agent: Uses libraries in microservice development
- Integration Agents: Creates libraries for external service integration
Related Documents¶
- Library Template Overview - General library template
- Microservice Template - Microservice template
- Template Architecture Implementation - Template architecture