ASP.NET Core Web API

Rate Limiting & Throttling

1 Views Updated 5/4/2026

Making External Requests (IHttpClientFactory)

Modern Microservices constantly talk to each other. Your API might need to hit Stripe's API to process a card, or an AWS endpoint to grab an image. While manually typing new HttpClient() seems easy, it is a catastrophic memory-leak anti-pattern that will eventually crash your entire server via Socket Exhaustion.

1. Socket Exhaustion: The Danger of new HttpClient()

Whenever you instantiate new HttpClient(), under the hood it opens physical network sockets on the operating system to send the bytes. When you dispose of the client after the request, the OS physically keeps that socket "half-open" (in a TIME_WAIT state) for up to 4 minutes.

❌ The Server Crash

If your API receives 5,000 requests, and each request instantiates a new HttpClient(), you just exhausted 5,000 network sockets. The server has run out of ports. The 5,001st request will throw an extreme fatal Exception and the server halts.

2. The Solution: IHttpClientFactory

Instead of manually creating clients, ASP.NET Core introduced IHttpClientFactory. It maintains a secure internal pool of HTTP connections. Instead of destroying the socket, it recycles it efficiently.

Step 1: Register in Program.cs

var builder = WebApplication.CreateBuilder(args);

// Register the factory into the Dependency Injection container
builder.Services.AddHttpClient(); 

Step 2: Inject into the Controller

[ApiController]
[Route("api/external")]
public class ExternalDataController : ControllerBase
{
    private readonly IHttpClientFactory _httpClientFactory;

    public ExternalDataController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    [HttpGet("github-profile")]
    public async Task<IActionResult> GetGithubData()
    {
        // 1. Ask the factory for a safe client
        var client = _httpClientFactory.CreateClient();

        // 2. Make the external request
        var response = await client.GetAsync("https://api.github.com/users/octocat");
        
        if (response.IsSuccessStatusCode)
        {
            // Safely read the JSON payload
            var content = await response.Content.ReadAsStringAsync();
            return Ok(content);
        }
        
        return StatusCode(500, "Failed to reach GitHub API.");
    }
}

3. Typed Clients (The Enterprise Standard)

Constantly typing out base URLs and API Keys into every controller logic is messy. We should encapsulate the HttpClient into its own dedicated Service Class.

1. Create the strongly-typed Service

public class GithubApiService
{
    private readonly HttpClient _client;

    // The factory injects the HttpClient directly into this constructor!
    public GithubApiService(HttpClient client)
    {
        _client = client;
        _client.BaseAddress = new Uri("https://api.github.com/");
        _client.DefaultRequestHeaders.Add("User-Agent", "MyCompany-App");
    }

    public async Task<string> GetProfileAsync(string username)
    {
        return await _client.GetStringAsync($"users/{username}");
    }
}

2. Register it beautifully in Program.cs

// Automatically wires the factory to this specific service!
builder.Services.AddHttpClient<GithubApiService>();

4. Interview Mastery

Q: "When an external API goes completely offline, our `await client.GetAsync()` call might hang for 100 seconds before timing out, blocking our internal threads. How do we prevent cascading failures when external services die?"

Architect Answer: "We use the Polly library to implement the Circuit Breaker pattern. Using the `IHttpClientFactory`, we attach Polly to the `AddHttpClient` registration. We define rules saying: 'If GitHub fails 5 times in a row, physically break the circuit.' Instead of letting the 6th HTTP Request wait 100 seconds for a timeout, the Circuit Breaker instantly intercepts the 6th request and immediately returns a failure. This prevents our web server from starving its Thread Pool while waiting for a definitively dead external service."

ASP.NET Core Web API
1. Fundamentals & HTTP
Introduction to ASP.NET Core Web API REST Principles and HTTP Methods Controllers & ControllerBase Routing (Attribute vs Conventional) Action Return Types (IActionResult)
2. Request Handling
Model Binding (FromQuery, FromBody, FromRoute) Dependency Injection (DI) Deep Dive App Settings & The Options Pattern
3. Data Access & Architecture
EF Core Setup in Web API DbContext & Migrations Repository & Unit of Work Pattern Asynchronous Programming (async/await)
4. Data Transfer & Validation
Data Transfer Objects (DTOs) & AutoMapper Model Validation (DataAnnotations) FluentValidation Integration
5. Advanced Concepts
Global Exception Handling Middleware Content Negotiation (JSON vs XML) Pagination & Filtering Advanced Searching & Sorting HATEOAS (Hypermedia) Implementation Output Caching & Response Caching
6. Security & Authorization
Cross-Origin Resource Sharing (CORS) JWT Authentication Setup Access Tokens & Refresh Tokens Workflow Role-Based & Policy-Based Authorization API Key Authentication Rate Limiting & Throttling
7. Documentation & Testing
Swagger & OpenAPI Configuration Customizing API Documentation Unit Testing Controllers (xUnit & Moq) Integration Testing (WebApplicationFactory)
8. Microservices & Deployment
Consuming External APIs (IHttpClientFactory) Health Checks & Diagnostics API Versioning Strategies Deploying APIs (Docker & Azure)