HttpClient in Blazor Webassembly


httpclient in blazor webassembly

How to make http calls to send and receive server-side from a blazor webassembly app. A Blazor Webassembly application runs on the client-side in the browser. What if the application needs server-side data. Well, it can communicate with the server over http.

how to call rest api from blazor webassembly

In Blazor we use a class called HttpClient to make http calls to send and receive data from an API. In both the hosting models, that is Blazor WebAssembly and Blazor Server we use this same HttpClient class. 

There are several approcahes to use this HttpClient class. A word of caution though, if not implemented correctly it can lead to problems like socket exhaustion or failing to handle DNS changes. Going through all these different approaches is too time consuming and only makes it more confusing.

httpclient blazor webassembly

So to keep it simple, let's use the recommended approach. For real world enterprise apps, the recommended approach is to use IHttpClientFactory. This approach works with both the hosting models, that is, Blazor Webassembly and Blazor Server. It's the same code that we use in both the hosting models which means it's easy to convert a Blazor Server app to a Blazor Webassembly app and vice-versa. It also offers several benefits like providing a central location for configuring HttpClient instances, it also avoids the problems like failing to handle DNS changes and socket exhaustion. The following are the steps to use IHttpClientFactory.

Step 1 : Implement a wrapper service 

For separation of concerns implement a wrapper service that uses the HttpClient instance to call server side REST API to send and receive data. 

blazor webassembly httpclient example

If you are wondering why a separate wrapper service? Well, for separation of concerns. We do not want our Blazor components to be doing too many things. If a component needs server side data, it injects this wrapper service and calls it. So, our natural first step is to implement a wrapper service that calls server side REST API using the built-in HttpClient class.

Create Services folder in BlazorProject.Client project and the following 2 files (IEmployeeService.cs and EmployeeService.cs)

IEmployeeService.cs

using BlazorProject.Shared;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace BlazorProject.Client.Services
{
    public interface IEmployeeService
    {
        Task<IEnumerable<Employee>> Search(string name, Gender? gender);
        Task<IEnumerable<Employee>> GetEmployees();
        Task<Employee> GetEmployee(int employeeId);
        Task<Employee> GetEmployeeByEmail(string email);
        Task<Employee> AddEmployee(Employee employee);
        Task<Employee> UpdateEmployee(Employee employee);
        Task DeleteEmployee(int employeeId);
    }
}

EmployeeService.cs

We only provided implementation for GetEmployees() method. We will implement the rest of the methods in our upcoming videos.

using BlazorProject.Shared;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

namespace BlazorProject.Client.Services
{
    public class EmployeeService : IEmployeeService
    {
        private readonly HttpClient httpClient;

        public EmployeeService(HttpClient httpClient)
        {
            this.httpClient = httpClient;
        }

        public async Task<IEnumerable<Employee>> GetEmployees()
        {
            return await httpClient.GetFromJsonAsync<IEnumerable<Employee>>("api/employees");
        }

        public Task<Employee> AddEmployee(Employee employee)
        {
            throw new NotImplementedException();
        }

        public Task DeleteEmployee(int employeeId)
        {
            throw new NotImplementedException();
        }

        public Task<Employee> GetEmployee(int employeeId)
        {
            throw new NotImplementedException();
        }

        public Task<Employee> GetEmployeeByEmail(string email)
        {
            throw new NotImplementedException();
        }

        public Task<IEnumerable<Employee>> Search(string name, Gender? gender)
        {
            throw new NotImplementedException();
        }

        public Task<Employee> UpdateEmployee(Employee employee)
        {
            throw new NotImplementedException();
        }
    }
}

GetFromJsonAsync method in .NET

GetFromJsonAsync sends an HTTP GET request and parses the JSON response body to create an object. This method is in System.Net.Http.Json namespace. In addition to GetFromJsonAsync(), we also have PostAsJsonAsync(), PutAsJsonAsync() and DeleteAsync()

httpclient communication in blazor webassembly

Step 2 : Install Microsoft.Extensions.Http nuget package

Includes the AddHttpClient extension method for IServiceCollection

Step 3 : Configure IHttpClientFactory and related services

In the Main() method in Program.cs file, add IHttpClientFactory and related services

builder.Services.AddHttpClient<IEmployeeService, EmployeeService>(client =>
{
    client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
});

Since we are using the IHttpClientFactory to configure HttpClient we no longer need the following code.

//builder.Services.AddScoped(sp =>
//new HttpClient
//{
//    BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
//});

Step 4 : Inject wrapper service in Blazor components

public List<Employee> Employees { get; set; }

[Inject]
public IEmployeeService EmployeeService { get; set; }

protected override async Task OnInitializedAsync()
{
    Employees = (await EmployeeService.GetEmployees()).ToList();
}




© 2020 Pragimtech. All Rights Reserved.