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.

Unleash Blazor's Potential

Blazor promises to make it much easier (and faster) to build modern, responsive web applications, using the tools you already know and understand.

Subscribe to my Practical ASP.NET Blazor newsletter and get instant access to the vault.

In there you'll find step-by-step tutorials, source code and videos to help you get up and running using Blazor's component model.

I respect your email privacy. Unsubscribe 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.

Source code, step-by-step tutorials, videos and more

I've compiled a whole load of useful tutorials, source code for articles (like this one) and mini video series to help you push through all the noise and build better ASP.NET web applications, faster.

Drop your email in the box below to get new posts first, and instant access to 'the vault'.

I respect your email privacy. Unsubscribe with one click.

 

Next up

Use a recursive Blazor component to render a TreeView
How to render nested “nodes” in a TreeView
Inject content into your Blazor components with typed Render Fragments
Maintain clear separation between your components and “inject” the markup you need
Using .NET 7’s Blazor Custom Elements to render dynamic content
Render Blazor components from dynamic content, at runtime?