If you’re building a Blazor WASM application you’re almost certainly going to wind up making calls to an API.

The typical way to do this is to use HttpClient:

@using System.Net.Http
@using System.Net.Http.Json
@using System.Threading.Tasks
@inject HttpClient Http

@code {

    private Customer[] customers;
    
    protected override async Task OnInitializedAsync() {
        customers = await Http.GetFromJsonAsync<Customer[]>("api/Customer");
    }

}

This works well, but it does carry a few limitations.

Firstly, your Blazor components are suddenly very tied to that "api/Customer" magic string for the URL of the API endpoint.

If you find yourself making similar calls from more than one component you’re probably going to end up referencing the same endpoint multiple times in different places, meaning any changes to the URL and you’ll be updating multiple components.

Secondly, the API isn’t very discoverable for you or any other developer working on the project.

To consume the API you have to know:

  • The URL of the endpoint
  • The type of the response
  • Potentially the shape (or type) of any data needed for the request

I recently had the chance to work on a new Blazor project and found myself facing these problems, so I had a look for an alternative approach.

Refit can take care of the boilerplate code for you

With Refit you can create a strongly typed interface for your API which moves all this knowledge about URLs, request and response types into one place.

Assuming you already have an API up and running as per our example earlier, you can create a Refit API client like this:

using Refit;

public interface CustomerApi {

    [Get("/Customer")]
    Task<Customer[]> List();

}

You’ll also need a little bit of configuration in your Blazor’s program.cs file.

private static async Task Run(WebAssemblyHostBuilder builder, string[] args)
{
    var apiUrl = "http://localhost:5001/api";    

    builder.Services.AddRefitClient<CustomerApi>()
        .ConfigureHttpClient(c => { c.BaseAddress = new Uri(apiUrl); });
    
    // other code...
}

Now you can happily go ahead and invoke the Api from your Blazor components.

@inject CustomerApi CustomerApi

@code {

    private Customer[] customers;
    
    protected override async Task OnInitializedAsync() {
        customers = await CustomerApi.List();
    }

}

This takes a lot of the guesswork out of consuming your API.

Once this Refit API is in place you can make use of it to call your API without constantly trying to remember (and/or find out) which URL, request or response type to use.

Considering Blazor for your next project?

Try this simple, repeatable process for transforming ideas into features using Blazor's component model.

4 days; 4 emails; enter your email in the box below and I'll send you lesson #1.

I respect your email privacy. No spam, unsubscribe anytime with one click.

 

Naturally it works for HTTP POST requests as well:

using Refit;

public interface CustomerApi {

    [Get("/Customer")]
    Task<Customer[]> List();

    [Post("/Customer")]
    Task Create(Customer customer);

}

Automatically attaching JWTs

Blazor can automatically attach JWT access tokens to your outgoing requests if you configure your Http Client to use AuthorizationMessageHandler.

Under the hood this makes sure the authorization request header includes your Bearer access token (if you’re logged in to the application).

Here’s how I was able to get that working with Refit.

private static async Task Run(WebAssemblyHostBuilder builder, string[] args)
{
    var apiUrl = "http://localhost:5001/api";    

    builder.Services.AddRefitClient<CustomerApi>()
        .ConfigureHttpClient(c => { c.BaseAddress = new Uri(apiUrl); })
        .AddHttpMessageHandler(sp => sp.GetRequiredService<AuthorizationMessageHandler>()
            .ConfigureHandler(new[] {apiUrl}));
    
    // other code...
}

The key is to make sure you configure the handler with the base address for your API (the call to ConfigureHandler).

AuthorizationMessageHandler will only attach tokens when you make requests to a URI which starts with that Base URL.

In summary

You can cut down on some boilerplate code, reduce the number of magic strings and improve the discoverability of your API by using the handy Refit library.

Find out more at the Refit Github repository.

Build better ASP.NET web applications, faster

I email every week with hints, tips and advice on how to push through all the noise to get your ASP.NET applications built.

Drop your email in the box below and I'll send new articles straight to your inbox.

I respect your email privacy. No spam, unsubscribe anytime with one click.

 

Next up

With so many Blazor Component Libraries, which one is best for you?
There’s no shortage of component libraries available for Blazor, but how do you figure out which one you should use?
Will .NET 6 fix Blazor Prerendering?
Prerendering eradicates Blazor WASM’s initial load time and .NET 6 promises to address its one key limitation
Persisting your users preferences using Blazor and Local Storage
Now your app supports dark mode, let’s make sure your visitors only have to choose it once (or ideally, not at all)