API Integration with .NET MAUI
Learn how to integrate with RESTful APIs in your .NET MAUI applications using modern C# and .NET features.
Introduction to API Integration
Modern mobile and desktop applications often need to interact with backend services to fetch and send data. .NET MAUI, leveraging the power of .NET, provides robust tools for making HTTP requests and handling responses efficiently.
Using HttpClient
The HttpClient
class is the primary way to send HTTP requests. It's designed to be instantiated once and reused throughout the life of an application.
Making a GET Request
Let's fetch data from a public API. We'll use the JSONPlaceholder API as an example.
using System;
using System.Net.Http;
using System.Threading.Tasks;
public class ApiService
{
private readonly HttpClient _httpClient;
public ApiService()
{
// It's recommended to instantiate HttpClient once and reuse it.
_httpClient = new HttpClient
{
BaseAddress = new Uri("https://jsonplaceholder.typicode.com/")
};
}
public async Task<string> GetPostsAsync()
{
try
{
HttpResponseMessage response = await _httpClient.GetAsync("posts");
response.EnsureSuccessStatusCode(); // Throws an exception if the status code is not 2xx
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
}
catch (HttpRequestException e)
{
Console.WriteLine($"Request error: {e.Message}");
return null; // Or throw a custom exception
}
}
}
Deserializing JSON Responses
The data returned from APIs is often in JSON format. .NET provides powerful tools for deserializing JSON into C# objects.
First, define a C# class that matches the structure of the JSON data:
public class Post
{
public int UserId { get; set; }
public int Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
}
Then, use System.Text.Json.JsonSerializer
to deserialize the response:
using System.Collections.Generic;
using System.Text.Json;
public class ApiService
{
// ... (HttpClient initialization as above) ...
public async Task<List<Post>> GetPostsAsObjectsAsync()
{
try
{
HttpResponseMessage response = await _httpClient.GetAsync("posts");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true // Handles case differences in JSON property names
};
List<Post> posts = JsonSerializer.Deserialize<List<Post>>(responseBody, options);
return posts;
}
catch (HttpRequestException e)
{
Console.WriteLine($"Request error: {e.Message}");
return null;
}
catch (JsonException e)
{
Console.WriteLine($"JSON deserialization error: {e.Message}");
return null;
}
}
}
Making a POST Request
To send data to an API, you'll typically use a POST request with a JSON payload.
using System.Net.Http.Json; // Requires System.Net.Http.Json NuGet package
public class ApiService
{
// ... (HttpClient initialization as above) ...
public async Task<Post> CreatePostAsync(Post newPost)
{
try
{
HttpResponseMessage response = await _httpClient.PostAsJsonAsync("posts", newPost);
response.EnsureSuccessStatusCode();
Post createdPost = await response.Content.ReadFromJsonAsync<Post>();
return createdPost;
}
catch (HttpRequestException e)
{
Console.WriteLine($"Request error: {e.Message}");
return null;
}
catch (JsonException e)
{
Console.WriteLine($"JSON deserialization error: {e.Message}");
return null;
}
}
}
Handling Authentication
Many APIs require authentication. Common methods include:
- API Keys: Often passed in headers (e.g.,
X-API-Key
) or as query parameters. - Bearer Tokens: Usually included in the
Authorization
header:Authorization: Bearer <your_token>
. - OAuth 2.0: A more complex but standard protocol for authorization.
Adding Authorization Headers
public class ApiService
{
private readonly HttpClient _httpClient;
private readonly string _apiKey = "YOUR_API_KEY"; // Replace with your actual API key
public ApiService()
{
_httpClient = new HttpClient
{
BaseAddress = new Uri("https://api.example.com/")
};
// Add a default header for API key authentication
_httpClient.DefaultRequestHeaders.Add("X-API-Key", _apiKey);
}
public async Task<string> GetDataWithApiKeyAsync()
{
try
{
HttpResponseMessage response = await _httpClient.GetAsync("data");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException e)
{
Console.WriteLine($"Request error: {e.Message}");
return null;
}
}
}
Error Handling and Resilience
Network requests can fail. Implement robust error handling and consider patterns for resilience:
- Check Status Codes: Always use
response.EnsureSuccessStatusCode()
or manually checkresponse.IsSuccessStatusCode
. - Handle Exceptions: Catch
HttpRequestException
and other potential exceptions. - Retries: Implement a retry mechanism for transient network errors.
- Timeouts: Configure timeouts for your
HttpClient
to prevent requests from hanging indefinitely.
Configuring Timeouts
using System.Net;
public class ApiService
{
private readonly HttpClient _httpClient;
public ApiService()
{
var httpClientHandler = new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
_httpClient = new HttpClient(httpClientHandler)
{
BaseAddress = new Uri("https://jsonplaceholder.typicode.com/"),
Timeout = TimeSpan.FromSeconds(30) // Set a default timeout of 30 seconds
};
}
// ... rest of the service ...
}
Best Practices
- Instantiate
HttpClient
once and reuse it. - Use asynchronous methods (
async/await
) for network operations. - Handle potential exceptions gracefully.
- Deserialize JSON responses into strongly-typed C# objects.
- Securely manage API keys and authentication tokens.
- Consider using libraries like Polly for advanced resilience patterns (retries, circuit breakers).
By following these guidelines, you can effectively integrate your .NET MAUI applications with external APIs, building powerful and data-rich user experiences.