.Net Maui Calling Rest Apis With Httpclient And Refit Complete Guide

 Last Update:2025-06-23T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    8 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of .NET MAUI Calling REST APIs with HttpClient and Refit


Exploring REST API Integration in .NET MAUI: HttpClient and Refit

Introduction

.NET Multi-platform App UI (MAUI) is a powerful framework for building full-fledged applications across multiple platforms—iOS, Android, and Windows—using C# and XAML. Central to many modern applications is the consumption of RESTful APIs, enabling seamless data exchange between the client and the server. This guide delves into two primary methods for API consumption in .NET MAUI: HttpClient and Refit.

Understanding RESTful APIs

REST (Representational State Transfer) is a stateless architecture for designing networked applications. It employs standard HTTP methods such as GET, POST, PUT, DELETE, and PATCH to manipulate resources identified by unique URIs. REST APIs are widely used due to their simplicity, efficiency, and platform independence.

Key Components:

  • Resources: Identified by unique URIs (e.g., https://api.example.com/users).
  • Representations: Data formats (e.g., JSON, XML).
  • Methods: Actions performed on resources:
    • GET: Retrieve data.
    • POST: Create new data.
    • PUT/PATCH: Update existing data.
    • DELETE: Remove data.

Status Codes:

  • 200 OK: Successful request.
  • 201 Created: Resource created successfully.
  • 400 Bad Request: Invalid request.
  • 401 Unauthorized: Authentication required.
  • 404 Not Found: Resource not found.
  • 500 Internal Server Error: Server-side issue.

HttpClient: The Basics

HttpClient is a built-in .NET class for accessing RESTful services and sending HTTP requests. It's a versatile tool providing fine-grained control over request configuration and response handling.

Advantages:

  • Cross-Platform Compatibility: Works seamlessly on iOS, Android, Windows, and macOS.
  • Minimal Overhead: No external dependencies; part of the .NET framework.
  • Performance: Efficient for low-level HTTP operations.

Basic Usage:

  1. Initiate HttpClient:

    HttpClient client = new HttpClient();
    
  2. Configure HttpClient (Optional):

    client.BaseAddress = new Uri("https://api.example.com");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
    client.DefaultRequestHeaders.Add("User-Agent", "MAUIApp");
    
  3. Send GET Request:

    HttpResponseMessage response = await client.GetAsync("users");
    if (response.IsSuccessStatusCode)
    {
        string data = await response.Content.ReadAsStringAsync();
        // Process JSON data
    }
    
  4. Send POST Request:

    var user = new { Name = "John Doe", Email = "john.doe@example.com" };
    string json = JsonConvert.SerializeObject(user);
    var content = new StringContent(json, Encoding.UTF8, "application/json");
    HttpResponseMessage response = await client.PostAsync("users", content);
    if (response.IsSuccessStatusCode)
    {
        string jsonResponse = await response.Content.ReadAsStringAsync();
        // Process response
    }
    
  5. Dispose HttpClient:

    client.Dispose();
    

Best Practices:

  • Singleton Pattern: Reuse a single instance of HttpClient to improve performance.
  • Timeout Configuration: Set appropriate timeouts to avoid hanging requests.
  • Error Handling: Gracefully handle exceptions and status codes.
  • Security: Use HTTPS for secure communication.

Example of Singleton HttpClient:

public static class HttpClientFactory
{
    private static readonly HttpClient _httpClient = new HttpClient();

    static HttpClientFactory()
    {
        _httpClient.BaseAddress = new Uri("https://api.example.com");
        _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    }

    public static HttpClient CreateClient()
    {
        return _httpClient;
    }
}

// Usage
HttpClient client = HttpClientFactory.CreateClient();
HttpResponseMessage response = await client.GetAsync("users");

Introduction to Refit

While HttpClient provides excellent control, it can be cumbersome for complex API interactions. Refit is a type-safe REST client for .NET, abstracting away the low-level details and reducing boilerplate code. It simplifies API consumption by allowing you to define interfaces and automatically generating the client implementation at runtime.

Advantages:

  • Type Safety: Compiler checks API definitions.
  • Clean Code: Interfaces with clear method signatures.
  • Attributes: Simplify configuration of HTTP requests.
  • Interceptor Support: Customize request and response processing.

Setting Up Refit:

  1. Install Refit NuGet Package:

    dotnet add package Refit
    
  2. Define API Interface:

    public interface IApiService
    {
        [Get("/users")]
        Task<List<User>> GetUsersAsync();
    
        [Post("/users")]
        Task CreateUserAsync([Body] User user);
    
        [Put("/users/{id}")]
        Task UpdateUserAsync(int id, [Body] User user);
    
        [Delete("/users/{id}")]
        Task DeleteUserAsync(int id);
    }
    
  3. Generate API Client:

    HttpClient httpClient = new HttpClient();
    IApiService apiService = RestService.For<IApiService>(httpClient, new RefitSettings
    {
        ContentSerializer = new SystemTextJsonContentSerializer(Options.Create(new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = true
        }))
    });
    
  4. Use API Client:

    // Fetch users
    List<User> users = await apiService.GetUsersAsync();
    
    // Create user
    var newUser = new User { Name = "Jane Doe", Email = "jane.doe@example.com" };
    await apiService.CreateUserAsync(newUser);
    
    // Update user
    var updatedUser = new User { Name = "Jane D.", Email = "jane.d@example.com" };
    await apiService.UpdateUserAsync(1, updatedUser);
    
    // Delete user
    await apiService.DeleteUserAsync(1);
    

Response Handling:

Refit supports various response handling strategies, including automatic deserialization of JSON responses into C# objects.

Example: Handling Complex Responses:

public interface IApiService
{
    [Get("/users/{id}")]
    Task<UserResponse> GetUserAsync(int id);
}

public class UserResponse
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Status { get; set; }
}

// Usage
IApiService apiService = RestService.For<IApiService>(httpClient);
UserResponse user = await apiService.GetUserAsync(1);

Error Handling:

Refit throws ApiException for HTTP errors, allowing you to handle specific status codes and messages.

Example: Error Handling:

try
{
    await apiService.CreateUserAsync(newUser);
}
catch (ApiException ex)
{
    if (ex.StatusCode == HttpStatusCode.Conflict)
    {
        // Handle conflict error
    }
    else
    {
        // Handle other errors
    }
}

Customization:

Refit supports various customization options, including request headers, deserialization settings, and custom content types.

Example: Custom Request Headers:

public interface IApiService
{
    [Get("/users")]
    [Headers("Authorization: Bearer {token}")]
    Task<List<User>> GetUsersAsync([Header("Authorization")] string token);
}

// Usage
string authToken = "your_auth_token_here";
List<User> users = await apiService.GetUsersAsync(authToken);

Conclusion

Integrating REST APIs into .NET MAUI applications is essential for building dynamic and responsive apps. Both HttpClient and Refit offer robust solutions for API consumption, with HttpClient providing fine-grained control and Refit simplifying complex interactions through type-safe interfaces. Understanding these tools and best practices will enable you to build efficient, scalable, and maintainable applications.


Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement .NET MAUI Calling REST APIs with HttpClient and Refit

Example 1: Calling REST API with HttpClient

Step 1: Create a New .NET MAUI Project

  1. Open Visual Studio.
  2. Go to File > New > Project.
  3. Select .NET MAUI App (Preview).
  4. Provide a project name and location, then click Create.

Step 2: Add Model Classes

Let's assume you want to fetch data from an API that returns a list of users in JSON format. Create a model class to represent a user.

// Models/User.cs
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

Step 3: Create a Service to Handle HTTP Requests

Create a service class that uses HttpClient to make requests to the REST API.

// Services/UserService.cs
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;

public class UserService
{
    private readonly HttpClient _httpClient;

    public UserService()
    {
        _httpClient = new HttpClient();
    }

    public async Task<List<User>> GetUsersAsync()
    {
        var response = await _httpClient.GetAsync("https://jsonplaceholder.typicode.com/users");

        if (response.IsSuccessStatusCode)
        {
            var content = await response.Content.ReadAsStringAsync();
            var users = JsonConvert.DeserializeObject<List<User>>(content);
            return users;
        }

        throw new Exception($"Error: {response.StatusCode}");
    }
}

Step 4: Use the Service in Your ViewModel

Create a ViewModel to interact with the service and hold the data.

// ViewModels/UserViewModel.cs
using System.Collections.ObjectModel;
using System.Threading.Tasks;

public class UserViewModel
{
    private readonly UserService _userService;

    public ObservableCollection<User> Users { get; set; } = new ObservableCollection<User>();

    public UserViewModel()
    {
        _userService = new UserService();
    }

    public async Task LoadUsersAsync()
    {
        var users = await _userService.GetUsersAsync();
        foreach (var user in users)
        {
            Users.Add(user);
        }
    }
}

Step 5: Bind the ViewModel to the UI

In your MainPage.xaml, set up a ListView to display the users.

<!-- MainPage.xaml -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiAppWithHttpClient.MainPage">

    <CollectionView x:Name="UsersListView">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Label Grid.Column="0" Text="{Binding Id}" FontAttributes="Bold" />
                    <Label Grid.Column="1" Text="{Binding Name}" Margin="5,0,0,0" />
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

In your MainPage.xaml.cs, set the binding context and call LoadUsersAsync().

// MainPage.xaml.cs
using System.Threading.Tasks;
using Microsoft.Maui.Controls;

public partial class MainPage : ContentPage
{
    private UserViewModel _viewModel;

    public MainPage()
    {
        InitializeComponent();
        _viewModel = new UserViewModel();
        BindingContext = _viewModel;
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        await _viewModel.LoadUsersAsync();
        UsersListView.ItemsSource = _viewModel.Users;
    }
}

Step 6: Install Newtonsoft.Json Package

If not already installed, install the Newtonsoft.Json package via NuGet:

  • Right-click on the project in Solution Explorer.
  • Select Manage NuGet Packages.
  • Search for Newtonsoft.Json and install it.

Step 7: Run the Application

Run your application on any available platform, such as Android, iOS, or Windows.


Example 2: Calling REST API with Refit

Step 1: Create a New .NET MAUI Project

Follow the same steps as above to create a new project.

Step 2: Add Model Classes

Use the same model class as before.

// Models/User.cs
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

Step 3: Define an API Interface

Using Refit, define an API interface for the HTTP requests.

// Services/IUserApi.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Refit;

public interface IUserApi
{
    [Get("/users")]
    Task<List<User>> GetUsersAsync();
}

Step 4: Create a Service to Handle API Requests

Use Refit to generate the API service from the interface.

// Services/UserService.cs
using Refit;
using System.Threading.Tasks;

public class UserService
{
    private readonly IUserApi _userApi;

    public UserService()
    {
        _userApi = RestService.For<IUserApi>("https://jsonplaceholder.typicode.com");
    }

    public async Task<List<User>> GetUsersAsync()
    {
        return await _userApi.GetUsersAsync();
    }
}

Step 5: Use the Service in Your ViewModel

Again, create a ViewModel to interact with the service and hold the data.

// ViewModels/UserViewModel.cs
using System.Collections.ObjectModel;
using System.Threading.Tasks;

public class UserViewModel
{
    private readonly UserService _userService;

    public ObservableCollection<User> Users { get; set; } = new ObservableCollection<User>();

    public UserViewModel()
    {
        _userService = new UserService();
    }

    public async Task LoadUsersAsync()
    {
        var users = await _userService.GetUsersAsync();
        foreach (var user in users)
        {
            Users.Add(user);
        }
    }
}

Step 6: Bind the ViewModel to the UI

The binding context and UI setup are the same as in Example 1.

<!-- MainPage.xaml -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiAppWithRefit.MainPage">

    <CollectionView x:Name="UsersListView">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Label Grid.Column="0" Text="{Binding Id}" FontAttributes="Bold" />
                    <Label Grid.Column="1" Text="{Binding Name}" Margin="5,0,0,0" />
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>
// MainPage.xaml.cs
using System.Threading.Tasks;
using Microsoft.Maui.Controls;

public partial class MainPage : ContentPage
{
    private UserViewModel _viewModel;

    public MainPage()
    {
        InitializeComponent();
        _viewModel = new UserViewModel();
        BindingContext = _viewModel;
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        await _viewModel.LoadUsersAsync();
        UsersListView.ItemsSource = _viewModel.Users;
    }
}

Step 7: Install Refit Package

Install the Refit package via NuGet:

  • Right-click on the project in Solution Explorer.
  • Select Manage NuGet Packages.
  • Search for Refit and install it.

Step 8: Run the Application

Run your application on any available platform, such as Android, iOS, or Windows.


You May Like This Related .NET Topic

Login to post a comment.