.NET MAUI Calling REST APIs with HttpClient and Refit Step by step Implementation and Top 10 Questions and Answers
 Last Update: April 01, 2025      16 mins read      Difficulty-Level: beginner

.NET MAUI Calling REST APIs with HttpClient and Refit

.NET Multi-platform App UI (MAUI) is a framework that allows developers to create cross-platform applications for Windows, macOS, iOS, and Android using C#. When developing these applications, interacting with REST APIs is a common requirement. The two primary tools for making HTTP requests in .NET MAUI are HttpClient and Refit. Below, we will explore both tools in detail, providing important information to help you effectively integrate REST API calls into your .NET MAUI applications.

Using HttpClient

HttpClient is a flexible and powerful tool for making HTTP requests in .NET. It has been a part of the .NET framework since .NET 4.5 and is available in .NET MAUI without any additional dependencies.

Creating and Configuring HttpClient

Start by adding the System.Net.Http package to your project if it's not already included. Then, you can create an instance of HttpClient:

using System.Net.Http;

public class ApiService
{
    private static readonly HttpClient _httpClient;

    static ApiService()
    {
        _httpClient = new HttpClient();
        // Configure the base address, headers, etc.
        _httpClient.BaseAddress = new Uri("https://api.example.com/");
        _httpClient.DefaultRequestHeaders.Accept.Clear();
        _httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
    }

    public async Task<string> GetDataAsync(int id)
    {
        using (var response = await _httpClient.GetAsync($"data/{id}"))
        {
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsStringAsync();
            }
            else
            {
                return null; // Handle errors appropriately
            }
        }
    }

    public async Task<bool> PostDataAsync(string data)
    {
        using (var content = new StringContent(data, System.Text.Encoding.UTF8, "application/json"))
        using (var response = await _httpClient.PostAsync("data", content))
        {
            return response.IsSuccessStatusCode;
        }
    }
}

Important Points

  • Singleton HttpClient: In the example above, HttpClient is configured as a singleton. Creating a new HttpClient instance for every request can lead to socket exhaustion. Reuse HttpClient instances when possible.
  • Error Handling: Always check the IsSuccessStatusCode property of the HttpResponseMessage to handle HTTP errors.
  • Timeouts and Cancellation: Consider setting timeouts and handling cancellations to prevent hanging requests.

Using Refit

Refit is a type-safe REST client library for .NET, which abstracts the HTTP calls and maps API endpoints to C# method calls. It uses attributes and interfaces to simplify API consumption.

Installing Refit

First, add the Refit package to your project:

dotnet add package Refit

Creating an API Interface

Define an interface with methods that represent the API endpoints:

using Refit;

public interface IApiService
{
    [Get("/data/{id}")]
    Task<string> GetDataAsync(int id);

    [Post("/data")]
    [Headers("Content-Type: application/json")]
    Task<bool> PostDataAsync([Body] string data);
}

Creating a Refit Client

Create a client using the RestService.For method:

using Refit;
using System;

public class ApiService
{
    private static readonly IApiService _apiService;

    static ApiService()
    {
        var settings = new RefitSettings
        {
            LogLevel = LogLevel.Basic,
        };
        
        _apiService = RestService.For<IApiService>("https://api.example.com/", settings);
    }

    public Task<string> GetDataAsync(int id)
    {
        return _apiService.GetDataAsync(id);
    }

    public Task<bool> PostDataAsync(string data)
    {
        return _apiService.PostDataAsync(data);
    }
}

Important Points

  • Type Safety: Refit provides compile-time type checking for API calls, reducing the risk of errors.
  • Auto-Serialization: Refit automatically handles JSON serialization and deserialization, simplifying the process of working with API data.
  • Customization: Refit supports various customization options, such as logging, content negotiation, and message handlers, allowing you to tailor the behavior of your API client to your needs.

Conclusion

Both HttpClient and Refit are powerful tools for making HTTP requests in .NET MAUI applications. HttpClient offers a more manual approach with greater flexibility and control, while Refit provides a simpler and more abstracted way to work with REST APIs. By understanding the strengths and limitations of each tool, you can choose the one that best fits your project's requirements.

  • HttpClient is ideal for projects that require fine-grained control over HTTP requests, handling of non-standard APIs, or complex scenarios where type safety is not critical.
  • Refit is a great choice for projects that value simplicity, type safety, and ease of maintenance, especially when working with well-defined REST APIs.

By leveraging these tools effectively, you can build robust and responsive applications that efficiently interact with REST APIs.

Examples, Set Route and Run the Application, Then Data Flow: Step-by-Step for Beginners in .NET MAUI Calling REST APIs with HttpClient and Refit

Welcome to the journey of learning how to call REST APIs in .NET MAUI using HttpClient and Refit. This guide aims to break down the process into easily digestible steps, making it accessible for beginners. We will cover configuring routes, setting up your application, and tracing the data flow.

1. Setting Up Your .NET MAUI Project

First, ensure you have the latest version of .NET MAUI installed. You can set up a new project via Visual Studio or the .NET CLI.

Using Visual Studio:

  • File > New > Project > .NET MAUI App (C#).
  • Provide a name and choose a location for your project.
  • Click "Create".

Using .NET CLI:

dotnet new maui -n YourMAUIApp
cd YourMAUIApp

2. Understanding the Basics of REST APIs

Before diving into the implementation, it's essential to grasp what a REST API is:

  • REST (Representational State Transfer): It is an architectural style used for designing networked applications. The key aspects are statelessness, client-server, cacheable, and a uniform interface (methods like GET, POST, PUT, DELETE, etc.).
  • API (Application Programming Interface): It is a set of rules and protocols for building and interacting with software applications.

3. Calling REST APIs with HttpClient

Let's start with HttpClient, which is a popular method to consume web services.

Step a: Adding HttpClient to the Project

// Add HttpClient services in MauiProgram.cs
public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
        });

    // Add HttpClient to services
    builder.Services.AddHttpClient<WeatherService>(client =>
    {
        client.BaseAddress = new Uri("https://api.openweathermap.org/data/2.5/");
        client.DefaultRequestHeaders.Add("Accept", "application/json");
    });

    return builder.Build();
}

Step b: Creating the Service to Consume the API

// WeatherService.cs
public class WeatherService
{
    private readonly HttpClient _httpClient;

    public WeatherService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> GetWeatherDataAsync(string city)
    {
        var apiKey = "YOUR_API_KEY"; // Replace with actual API key
        var url = $"weather?q={city}&appid={apiKey}";

        using (var response = await _httpClient.GetAsync(url))
        {
            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadAsStringAsync();
            return result;
        }
    }
}

Step c: Injecting and Using the Service in a Page

// MainPage.xaml.cs
public partial class MainPage : ContentPage
{
    private readonly WeatherService _weatherService;

    public MainPage(WeatherService weatherService)
    {
        InitializeComponent();
        _weatherService = weatherService;
    }

    private async void BtnFetch_Clicked(object sender, EventArgs e)
    {
        var city = EntryCity.Text;
        if (!string.IsNullOrEmpty(city))
        {
            var result = await _weatherService.GetWeatherDataAsync(city);
            LblWeatherData.Text = result;
        }
    }
}

Step d: Running the Application Deploy your application on an emulator or a physical device. Enter a city name and click the fetch button. The weather data for that city should be displayed.

4. Calling REST APIs with Refit

Refit provides a powerful and elegant way to consume REST APIs with minimal boilerplate code.

Step a: Installing Refit

dotnet add package Refit

Step b: Defining the API Interface

// IWeatherApi.cs
using Refit;
using System.Threading.Tasks;

public interface IWeatherApi
{
    [Get("/weather")]
    Task<string> GetWeatherDataAsync([AliasAs("q")] string city, [AliasAs("appid")] string apiKey);
}

Step c: Setting Up Refit in the MauiProgram.cs

// MauiProgram.cs
public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
        });

    // Add Refit services
    builder.Services.AddRefitClient<IWeatherApi>(new RefitSettings
    {
        BaseAddress = new Uri("https://api.openweathermap.org/data/2.5/"),
        HttpMessageHandlerFactory = () => new HttpClientHandler
        {
            AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
        }
    });

    return builder.Build();
}

Step d: Consuming the API Using Refit

// WeatherService.cs (Refit version)
public class WeatherService
{
    private readonly IWeatherApi _weatherApi;

    public WeatherService(IWeatherApi weatherApi)
    {
        _weatherApi = weatherApi;
    }

    public async Task<string> GetWeatherDataAsync(string city)
    {
        var apiKey = "YOUR_API_KEY"; // Replace with actual API key
        return await _weatherApi.GetWeatherDataAsync(city, apiKey);
    }
}

The rest of the implementation remains the same as with HttpClient. Inject the WeatherService into your MainPage.xaml.cs and call the GetWeatherDataAsync method to fetch and display the weather data.

5. Data Flow Summary

HttpClient:

  • Setup: Add HttpClient services in MauiProgram.cs.
  • Implementation: Create a service class (WeatherService) to handle the API calls.
  • Usage: Inject the service into your page and call the API.
  • Execution Flow: Page (user input) > WeatherService (API call using HttpClient) > API > Response (JSON) > Page (display data).

Refit:

  • Setup: Add Refit services in MauiProgram.cs.
  • Implementation: Define an API interface (IWeatherApi) with methods mapped to HTTP endpoints.
  • Usage: Inject the interface into your service class and call the methods.
  • Execution Flow: Page (user input) > WeatherService (API call using Refit) > API > Response (JSON) > Page (display data).

6. Conclusion

By following these steps, you should now have a solid foundation on how to call REST APIs in .NET MAUI using both HttpClient and Refit. HttpClient provides more control and understanding of the HTTP request lifecycle, while Refit simplifies the process via method-based calls. Feel free to explore further and implement more complex functionalities as you become more comfortable with these concepts.

Happy coding!

Top 10 Questions and Answers: .NET MAUI Calling REST APIs with HttpClient and Refit

1. What is .NET MAUI and how does it integrate with REST APIs?

Answer: .NET Multi-platform App UI (.NET MAUI) is a framework for building native applications for multiple platforms (Android, iOS, macOS, and Windows) using a single codebase. Integrating REST APIs into .NET MAUI applications allows you to retrieve and send data over the internet using HTTP protocols. You can use tools like HttpClient for manual HTTP requests or Refit for a more streamlined approach with type safety and simplicity.

2. How do I make a simple HTTP GET request in .NET MAUI using HttpClient?

Answer: To make a simple HTTP GET request with HttpClient in .NET MAUI, you first need to instantiate an HttpClient object and then use the GetAsync method to send the request and wait for the response. Here's a basic example:

using System.Net.Http; // include System.Net.Http

public async Task<string> FetchData()
{
    using (var client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync("https://api.example.com/data");
        response.EnsureSuccessStatusCode();
        string responseBody = await response.Content.ReadAsStringAsync();
        return responseBody;
    }
}

3. What are the advantages and disadvantages of using HttpClient in .NET MAUI?

Answer: Advantages:

  • Built-in, widely supported, and provides a direct method for sending HTTP requests.
  • Offers fine-grained control over HTTP requests and responses.

Disadvantages:

  • Requires more boilerplate code for common tasks like deserializing responses.
  • Manually handling HTTP status codes and response validation can be cumbersome.

4. What is Refit, and how does it compare to HttpClient in .NET MAUI?

Answer: Refit is a type-safe HTTP client library that simplifies making HTTP requests in .NET applications, including .NET MAUI. Refit abstracts much of the boilerplate code required for using HttpClient by defining API interfaces. It automatically maps HTTP requests and responses to strongly-typed C# objects.

Here’s how it compares to HttpClient:

  • Refit: Less boilerplate code, more concise and easier to maintain. Automatically handles serialization/deserialization of request bodies and response content.
  • HttpClient: More control over low-level HTTP details, but requires handling more code manually.

5. How do I create an interface to call a REST API using Refit in .NET MAUI?

Answer: To create an interface for a REST API using Refit in .NET MAUI:

  1. Define an interface with methods corresponding to API endpoints, annotate them with HTTP attributes ([Get], [Post], etc.).
  2. Use RestService.For<T>() to create an instance of the API client.

Here’s an example interface:

using Refit;

public interface IApiService
{
    [Get("/api/items")]
    Task<List<Item>> GetItemsAsync();

    [Post("/api/items")]
    Task<Item> CreateItemAsync([Body] Item item);
}

6. How can I handle API authentication with OAuth2 in .NET MAUI using HttpClient?

Answer: Handling OAuth2 authentication using HttpClient involves obtaining an access token from an authorization server and then including it with HTTP requests. Here's a simplified example:

public class AuthenticatedHttpClientHandler : HttpClientHandler
{
    private readonly string _accessToken;

    public AuthenticatedHttpClientHandler(string accessToken)
    {
        _accessToken = accessToken;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);
        return base.SendAsync(request, cancellationToken);
    }
}

7. What are some best practices for managing HttpClient in .NET MAUI applications?

Answer:

  • Reuse HttpClient Instances: Creating and disposing of HttpClient instances frequently can lead to socket exhaustion; instead, create a single instance and reuse it throughout the app's lifetime.
  • Handle Exceptions: Check response status codes and handle exceptions to manage errors gracefully.
  • Timeout Setting: Configure appropriate timeouts to prevent your app from hanging indefinitely.
  • Secure HTTP: Always use HTTPS to encrypt data in transit and prevent eavesdropping.
  • Error Logging: Log errors systematically for monitoring and debugging purposes.
  • Dispose of Resources: Use using statements (or equivalent Dispose calls) to clean up HttpClient and other resources to avoid memory leaks.

8. How do I handle JSON deserialization in .NET MAUI using HttpClient and Refit?

Answer: For HttpClient, you can use JsonConvert from Newtonsoft.Json or System.Text.Json to deserialize JSON responses:

string json = await response.Content.ReadAsStringAsync();
var items = JsonConvert.DeserializeObject<List<Item>>(json);

With Refit, deserialization is handled automatically when you define the API interface correctly. Refit uses System.Text.Json by default but can be configured to use other serializers if needed.

9. Can Refit handle different HTTP methods (GET, POST, PUT, DELETE)?

Answer: Yes, Refit supports multiple HTTP methods such as GET, POST, PUT, DELETE, etc., via corresponding interface method attributes: [Get], [Post], [Put], [Delete]. You can define parameters for these methods using attributes like [Get], [Post], [Put], [Delete], [Body], [Query], and [Header] to control how data is sent and received.

Example of a PUT and DELETE method in Refit interface:

[Put("/api/items/{id}")]
Task<Item> UpdateItemAsync(int id, [Body] Item item);

[Delete("/api/items/{id}")]
Task DeleteItemAsync(int id);

10. How can I test API calls in .NET MAUI applications using mocking frameworks such as Moq?

Answer: Mocking frameworks like Moq can be used to simulate Refit API calls or mock HttpClient for integration testing. With Refit, you can mock the interface:

var mockApiService = new Mock<IApiService>();
mockApiService
    .Setup(api => api.GetItemsAsync())
    .ReturnsAsync(new List<Item>());

For HttpClient, you can use a HttpMessageHandlerMock:

var mockHandler = new Mock<HttpMessageHandler>();
mockHandler.Setup(handler => handler.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<CancellationToken>()))
    .ReturnsAsync(new HttpResponseMessage() { 
        StatusCode = HttpStatusCode.OK, 
        Content = new StringContent("[{\"Id\":1,\"Name\":\"Item1\"}]") });

var client = new HttpClient(mockHandler.Object);

By leveraging these techniques, you can effectively manage and test API interactions in your .NET MAUI applications.