Refit and Apis in Blazor

A common problem Blazor developers have is ensuring that the application's business logic is not too tightly coupled to the Blazor application itself. For simple applications, that is fine. Meaning, you can put the core application logic inside your .razor files. But for larger applications hat have companion mobile apps for example, it is crucial to be able to call into common code from both the Blazor code, as well as the mobile app. This shared code must be made into a service and exposed via a separate http api that does not live inside the Blazor world. Does that mean that we have to write and deploy another separate Asp.Net Core application that hosts the api? Well, you could, but the beauty of Blazor is that it allows you to host both the Blazor application, as well as any number of apis.

But how do you access this api without having to write a lot of boilerplate? The traditional way is to use an HttpClient factory to create a client, create a request message, set the http method, url, query arguments, headers and serialize the body as json as needed. Then tell the client to make the request, wait for the response and then deserialize the json into your expected response object. That is tedious to say the least. Luckily there is a library called Refit that does all of that for you, and more! All that you have to do is define a Refit client interface, put it in a shared assembly and reference it both in your Blazor app and your mobile app (assuming it's a Xamarin app).

Hosting Apis

So how do you host your apis alongside your Blazor app? This one is actually quite easy, especially if you have worked with Asp.Net Core before. Inside your Startup.cs find the Configure method. Towards the end you will see a call to app.UseEndpoints. Depending on your hosting model (Server or WASM), there will already be certain calls inside the lambda. Simply add the following: endpoints.MapControllers();. Once controllers are mapped, the Asp.Net Core runtime will auto-discover any controller classes you have anywhere in your assembly, regardless of what namespace they are in. In case you are unsure of what controllers are, let's give a brief and contrived example:

public class ExampleController
{
    [HttpGet("/Api/Example/Echo/{text}")]
    public string Echo(string text)
    {
        return text;
    }
}

It's as simple as that. Now, if you make a GET request to /Api/Example/Hello in your browser, Postman or Fiddler, you will receive the responseHello. There are numerous flavors on how to configure controllers, so be sure to check out Microsoft's documentation.

Creating a Refit Client

Refit was first introduced back in 2014 and throughout the years it has evolved into an excellent and mature piece of software. Their documentation is excellent and thorough. Let's create our Refit client that will allow us to talk to our new Example endpoint. The first thing you have to do is create the following interface:

public interface IExampleClient
{
    [Get("/Api/Example/Echo/{text}")]
    string Echo(string text);
}

The interface name can be whatever you want, as can the function name. The return type must be the return type of the controller method you are mapping this to. Also, as you can probably tell, the method , path and arguments must also match the controller method. The above is saying that when the method Echo is called on this interface with the argument Hello, under the hood it will make a GET request to [RootUrl]/Api/Example/Echo/Hello. At this point two questions arise. One is how do I call a method on an interface if there is no implementation. And two, how does it know what the root url of the GET request is? The answer to both of those question is provided by the second thing you need to do to configure this client.

First, make sure you have the Refit Nuget package installed. Inside Startup.cs, find the ConfigureServices method. In there add the following:

services
    .AddRefitClient<IExampleClient>()
    .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://example.com"));

As easy as that. Now you can inject IExampleClient into any Blazor page: @inject IExampleClient ExampleClient. The simply call ExampleClient.Echo("Hello") anywhere you need to in the page. Under the hood, the Refit library will generate a concrete class that implements the interface for you. This generated class contains all the boilerplate code needed to make http requests. When you inject the interface, the dependency injection container will inject an instance of this generated class.

Using this same interface in your mobile app is even easier. Any time you need to make an api request, simply do the following:

var client = RestService.For<IExampleClient>("http://example.com");
var response = client.Echo("Hello");

Refit has a myriad of features and options, so please be sure to check the documentation. You can make use of everything ranging from query parameters, headers, authentication support, support for Polly (for automatic retries and timeouts) and more.

Start Blazorig Integration

With Start Blazoring We have controller and Refit support baked right in. Any time you need to create a new client, all you have to do is create the client interface and be sure it implements IApiClient. The system will auto-discover it by way of reflection and automatically register it, so you don't have to. Polly retry and timeout are pulled directly from the application configuration and applied to each client. Once you have defined your client interface, simply inject into any Blazor page as you would normally.

Table of Contents

  • Refit and Controllers

    We talk about how to create apis alongside your Blazor app and how to access those apis using Refit.

  • Blazor Gotchas

    This article explores various Blazor pitfalls that you should be aware of.

  • Blazor and HttpContext

    Here we discuss how to correctly use HttpContext in a Blazor app.

  • SignInManager and Blazor

    Blazor and SignInManager don't play well together. Let's see how to get around that.

  • One Year with Blazor

    We've switched over to using Blazor exclusively a year ago. Here are our thoughts.



An error has occurred. This application may no longer respond until reloaded. Reload 🗙