DEV Community

Cover image for Step-by-Step Guide: How to Integrate Third-Party APIs with .NET 8 Minimal APIs
Leandro Veiga
Leandro Veiga

Posted on

Step-by-Step Guide: How to Integrate Third-Party APIs with .NET 8 Minimal APIs

In today's world of modern web applications, integrating with third-party APIs is essential. Whether you're connecting to payment gateways, social media platforms, or external data providers, third-party APIs allow your application to expand its capabilities without reinventing the wheel. With .NET 8 Minimal APIs, integrating external services is straightforward and efficient.

In this post, I'll walk you through a step-by-step guide to integrating third-party APIs with .NET 8 Minimal APIs, ensuring your application communicates seamlessly with external systems.


Why Integrate Third-Party APIs?

Third-party APIs bring several benefits to your application:

  • Extend functionality: Add complex features (e.g., payments, maps, analytics) without building them from scratch.
  • Reduce development time: Leverage APIs built by specialists in their fields.
  • Enhance user experience: Provide services such as social login or real-time data updates that users expect.

Whether it's integrating with Stripe for payments, Google Maps for location services, or Twitter for social data, connecting to third-party APIs is a common task for most modern applications.


1. Setting Up a .NET 8 Minimal API Project

Before we jump into integrating third-party APIs, let’s set up a .NET 8 Minimal API project. If you haven’t done this before, here’s a quick start.

First, create a new .NET 8 Minimal API project:

dotnet new web -n ThirdPartyIntegrationDemo
cd ThirdPartyIntegrationDemo
Enter fullscreen mode Exit fullscreen mode

Next, open Program.cs and configure the basic structure of your Minimal API:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello, World!");

app.Run();
Enter fullscreen mode Exit fullscreen mode

You now have a basic Minimal API project ready to be extended with third-party integrations.


2. Consuming a Third-Party API

Now, let's dive into the process of consuming a third-party API using HttpClient. For this example, we'll use a free public API like OpenWeatherMap to fetch weather data.

Step 1: Install Required NuGet Packages

Before we proceed, ensure that you have the required packages installed:

dotnet add package Microsoft.Extensions.Http
Enter fullscreen mode Exit fullscreen mode

This package allows us to manage HTTP client instances efficiently using HttpClientFactory.

Step 2: Set Up HttpClient for the Third-Party API

Next, we’ll configure HttpClient to interact with OpenWeatherMap’s API. In your Program.cs, register the HttpClient with the DI container:

builder.Services.AddHttpClient("OpenWeatherMap", client =>
{
    client.BaseAddress = new Uri("https://api.openweathermap.org/data/2.5/");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
});
Enter fullscreen mode Exit fullscreen mode

This configuration sets the base URL for OpenWeatherMap and ensures that all requests are sent with a JSON accept header.

Step 3: Create a Service for the API Integration

Now, let's create a service that will handle communication with the OpenWeatherMap API. You can add this directly in Program.cs or, better yet, create a separate file for it.

public class WeatherService
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly string _apiKey = "YOUR_API_KEY"; // Replace with your OpenWeatherMap API key

    public WeatherService(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    public async Task<string> GetWeatherAsync(string city)
    {
        var client = _httpClientFactory.CreateClient("OpenWeatherMap");
        var response = await client.GetAsync($"weather?q={city}&appid={_apiKey}");

        if (response.IsSuccessStatusCode)
        {
            var result = await response.Content.ReadAsStringAsync();
            return result;
        }

        return "Unable to fetch weather data";
    }
}
Enter fullscreen mode Exit fullscreen mode

This service uses the HttpClientFactory to create an instance of HttpClient, sends a request to the OpenWeatherMap API, and returns the response as a string.

Step 4: Expose the Service Through a Minimal API Endpoint

Finally, expose the weather service through a Minimal API endpoint. In Program.cs, map the service to a route:

app.MapGet("/weather/{city}", async (WeatherService weatherService, string city) =>
{
    var weather = await weatherService.GetWeatherAsync(city);
    return Results.Ok(weather);
});
Enter fullscreen mode Exit fullscreen mode

With this route, users can query the weather for any city via /weather/{city}.


3. Handling API Responses

In the example above, we returned the raw response from the third-party API. However, it’s often necessary to deserialize the response into objects for easier manipulation and presentation.

Step 1: Define a DTO (Data Transfer Object)

Let’s define a DTO to model the weather data:

public class WeatherResponse
{
    public string Name { get; set; }
    public MainInfo Main { get; set; }

    public class MainInfo
    {
        public float Temp { get; set; }
        public float Humidity { get; set; }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Deserialize the Response

Modify the GetWeatherAsync method to deserialize the response into the WeatherResponse object using System.Text.Json:

public async Task<WeatherResponse> GetWeatherAsync(string city)
{
    var client = _httpClientFactory.CreateClient("OpenWeatherMap");
    var response = await client.GetAsync($"weather?q={city}&appid={_apiKey}");

    if (response.IsSuccessStatusCode)
    {
        var json = await response.Content.ReadAsStringAsync();
        var weatherResponse = JsonSerializer.Deserialize<WeatherResponse>(json);
        return weatherResponse;
    }

    return null;
}
Enter fullscreen mode Exit fullscreen mode

Now, when you call the /weather/{city} endpoint, the API will return a structured JSON response with the weather data for the specified city.


4. Error Handling and Logging

When consuming third-party APIs, it’s essential to handle errors gracefully and log any issues for debugging purposes.

Step 1: Add Basic Error Handling

In the GetWeatherAsync method, ensure that you return meaningful errors if something goes wrong:

if (!response.IsSuccessStatusCode)
{
    // Log the error and return a custom message
    return new WeatherResponse { Name = "Error", Main = new WeatherResponse.MainInfo { Temp = 0, Humidity = 0 } };
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Add Logging

Use the built-in logging framework to capture logs:

public class WeatherService
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly ILogger<WeatherService> _logger;
    private readonly string _apiKey = "YOUR_API_KEY";

    public WeatherService(IHttpClientFactory httpClientFactory, ILogger<WeatherService> logger)
    {
        _httpClientFactory = httpClientFactory;
        _logger = logger;
    }

    public async Task<WeatherResponse> GetWeatherAsync(string city)
    {
        try
        {
            var client = _httpClientFactory.CreateClient("OpenWeatherMap");
            var response = await client.GetAsync($"weather?q={city}&appid={_apiKey}");

            if (response.IsSuccessStatusCode)
            {
                var json = await response.Content.ReadAsStringAsync();
                return JsonSerializer.Deserialize<WeatherResponse>(json);
            }
            _logger.LogError($"Failed to fetch weather data for {city}: {response.StatusCode}");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"An error occurred while fetching weather data for {city}");
        }

        return null;
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Securing API Calls

Most third-party APIs require authentication, typically through API keys or OAuth tokens. For this example, we used an API key, but OAuth or JWT tokens are common in other services.

Storing API Keys Securely

Never hard-code API keys in your source code. Instead, store them in environment variables or use Azure Key Vault or AWS Secrets Manager for added security.

export OpenWeatherApiKey="YOUR_API_KEY"
Enter fullscreen mode Exit fullscreen mode

Then retrieve the key in your service:

private readonly string _apiKey = Environment.GetEnvironmentVariable("OpenWeatherApiKey");
Enter fullscreen mode Exit fullscreen mode

6. Testing Your API Integration

After setting up the integration, it’s important to write unit and integration tests to ensure everything works as expected.

Example Unit Test with Mocked HttpClient

You can mock the HttpClient responses for testing purposes:

public class WeatherServiceTests
{
    [Fact]
    public async Task GetWeatherAsync_ReturnsValidData()
    {
        // Arrange
        var mockFactory = new Mock<IHttpClientFactory>();
        var mockHttpMessageHandler = new Mock<HttpMessageHandler>();

        mockHttpMessageHandler
            .Protected()
            .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
            .ReturnsAsync(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent("{\"name\":\"London\",\"main\":{\"temp\":285.32,\"humidity\":75}}")
            });

        var client = new HttpClient(mockHttpMessageHandler.Object);
        mockFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(client);

        var service = new WeatherService(mockFactory.Object);



 // Act
        var result = await service.GetWeatherAsync("London");

        // Assert
        Assert.Equal("London", result.Name);
        Assert.Equal(285.32, result.Main.Temp);
    }
}
Enter fullscreen mode Exit fullscreen mode

This test mocks the HTTP response from the third-party API to verify that your service behaves as expected.


Conclusion

Integrating third-party APIs with .NET 8 Minimal APIs is a powerful way to extend your application’s functionality. With HttpClient, dependency injection, and secure API key handling, you can seamlessly connect to external services while maintaining high security and efficiency.

In this step-by-step guide, we've covered:

  • Setting up HttpClient for API integration.
  • Handling API responses with JSON deserialization.
  • Implementing robust error handling and logging.
  • Securing API calls with environment variables.

Whether you're integrating with payment gateways, social media platforms, or other external services, following these best practices will help you build reliable and maintainable API integrations.


By following this guide, you'll be well-equipped to integrate any third-party API with your .NET 8 Minimal API and create richer, more dynamic applications. Happy coding!

Top comments (0)