39

WebApi RestClient

WebApi RestClient is a library designed to simplify and streamline API calls to any type of web service. It integrates seamlessly with Microsoft's HttpClientFactory for managing HTTP clients and enables fluent API design for easy, readable code.

WebApi RestClient is a library designed to simplify and streamline API calls to any type of web service. It integrates with Microsoft's HttpClientFactory, leveraging its features for managing HTTP clients, such as connection pooling, lifecycle management, and centralized HttpClient configuration. The core feature of this library is the Fluent Architecture, which enables you to construct and send API requests in an intuitive and readable way, with a compact syntax that is easily configurable.

How to Use?

In your Program.cs file, you can register various HttpClient instances using the AddHttpClient method. This allows you to set common properties for API calls, ensuring that the logic for creating HttpClient is aligned with ASP.NET Core standards.

At the same time you have to add the line after register your httpclient:

builder.Services.AddRestClient();

Here is an example of how to configure a client:

services.AddHttpClient("api", client =>
{
    client.BaseAddress = new Uri("https://myapi.com/");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
});

At this point, you can use the HttpClientBuilderFactory class, which allows you to create a client by specifying its name (matching the name used in AddHttpClient).

var client = _httpClientBuilderFactory.CreateClient("api");

The CreateClient method will return an instance of HttpClientBuilder, which allows you to construct the API request in a Fluent manner.

Example Usage

With an instance of HttpClientBuilder, you can easily configure the API request by specifying the HTTP method, endpoint, query parameters, body, etc., using Fluent syntax.

Here is an example of a POST request with query parameters and a JSON body:

var response = await client
                    .WithMethod(HttpMethod.Post)
                    .WithEndpoint("login")
                    .WithQueryParameters(new Dictionary<string, string>
                    {
                        { "useCookies", "false" },
                        { "useSessionCookies", "false" }
                    })
                    .WithBody(new { email = "test@mail.com", password = "Passw0rd" })
                    .BuildRequest()
                    .SendAsync<LoginInfoResponse>();
 

In this example, the POST request is sent to the login endpoint with query parameters and a body containing login credentials. The response is then deserialized into the LoginInfoResponse object.

šŸ’” Blazor Server

In Blazor Server, you should register HttpClient using IHttpClientFactory, which is the recommended approach:

    services.AddHttpClient("api", client =>
    {
        client.BaseAddress = new Uri("https://jsonplaceholder.typicode.com/");
        client.DefaultRequestHeaders.Add("Accept", "application/json");
    });
 
    // Register RestClient 
    services.AddRestClient();

āœ” Advantages:

  • Uses IHttpClientFactory, which is the best practice for managing HTTP connections.
  • HttpClient is created and managed automatically by the DI container.

šŸ’” Blazor WebAssembly

In Blazor WebAssembly, IHttpClientFactory is NOT available because the app runs in the browser and uses HttpClient natively.

You should register it like this:

    builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("http://localhost:5154/") });
 
    // Register RestClient (passing WebAssemblyHostBuilder)
    builder.Services.AddRestClient(builder);

āœ” Advantages:

  • Directly provides HttpClient without relying on IHttpClientFactory.
  • AddRestClient(builder) ensures it works correctly in the client-side context.

šŸ’” Console Application

If you need to use HttpClient in a Console App, you must manually create a ServiceCollection:

    var services = new ServiceCollection();
 
    // Configure HttpClientFactory
    services.AddHttpClient("api", client =>
    {
        client.BaseAddress = new Uri("https://jsonplaceholder.typicode.com/");
        client.DefaultRequestHeaders.Add("Accept", "application/json");
    });
 
    // Register RestClient
    services.AddRestClient();
 
    var serviceProvider = services.BuildServiceProvider();
 
    // Retrieve HttpClient from DI container
    var clientFactory = serviceProvider.GetRequiredService<IHttpClientFactory>();
    var client = clientFactory.CreateClient("api");

āœ” Advantages:

  • Centralizes HttpClient management.
  • Uses IHttpClientFactory, which prevents socket exhaustion issues.

Response Handling

When you send a request, the library returns an object of type RestResponseWithData, which extends the base RestResponse class. This object contains several properties useful for handling the response state, such as the HTTP status code, status description, potential errors, and the data returned from the call.

public class RestResponse
{
    /// <summary>
    /// Indicates whether the status of the response is successful or not.
    /// </summary>
    public bool IsSuccessful { get; internal set; }
 
    /// <summary>
    /// Status code of the response.
    /// </summary>
    public HttpStatusCode StatusCode { get; internal set; }
 
    /// <summary>
    /// Description of the status of the response.
    /// </summary>
    public string? StatusDescription { get; internal set; }
 
    /// <summary>
    /// Any error message.
    /// </summary>
    public string? ErrorBody { get; internal set; }
}
public class RestResponseWithData<T> : RestResponse
{
    /// <summary>
    /// The data returned by the API response.
    /// </summary>
    public T? Data { get; internal set; }
}

This structure makes it easy to handle errors and data returned from API calls, centralizing the response management logic and improving code readability.

Key Features

  • Fluent API: Build and send API calls in an intuitive and readable manner.
  • Support for major HTTP methods: GET, POST, PUT, DELETE, etc.
  • Centralized HttpClient Management: Leverage the features of HttpClientFactory.
  • Automatic Response Deserialization: Automatically deserialize the returned data from the API call based on the specified type.
  • Error Handling: Easily manage errors and exceptions from API calls.