Azure / Azure/azure-functions-host
Analyzer: Suggested HttpClient Usage Pattern
- Dominant language
- C#
- Stars
- 2k
- Forks
- 482
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 38
Description
**Conditions To Trigger Analyzer**
Within a [Function]-decorated method, where a new HttpClient is instantiated..
```csharp
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.Http;
namespace TestManageConnectionApp
{
public static class HttpWrong
{
[FunctionName("TestHTTPWrong")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var testUri = new Uri("https://reqbin.com/echo");
var testHTTP = new HttpClient();
string responseBody = await testHTTP.GetStringAsync(testUri);
log.LogInformation("Here is the response body{0}", responseBody);
string responseMessage = "This is me saying Hello";
return new OkObjectResult(responseMessage);
}
}
}
```
**Diagnostic Level**
Warning
**How to fix violations**
1. Move HttpClient instantiation to a static instance defined outside of the [Function] (see example):
```csharp
namespace TestManageConnectionApp
{
public static class TestHTTPRight
{
static readonly HttpClient client = new HttpClient();
[FunctionName("TestHTTPRight")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var testUri = new Uri("https://reqbin.com/echo");
string responseBody = await client.GetStringAsync(testUri);
log.LogInformation("Here is the response body{0}", responseBody);
string responseMessage = "This is me saying Hello";
return new OkObjectResult(responseMessage);
}
}
}
```
2. Inject HttpClient with DI (see example):
```csharp
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
builder.Services.AddSingleton((s) => {
return new MyService();
});
builder.Services.AddSingleton();
}
}
}
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using System.Threading.Tasks;
namespace MyNamespace
{
public class MyHttpTrigger
{
private readonly HttpClient _client;
private readonly IMyService _service;
public MyHttpTrigger(HttpClient httpClient, IMyService service)
{
this._client = httpClient;
this._service = service;
}
[FunctionName("MyHttpTrigger")]
public async Task Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
var response = await _client.GetAsync("https://microsoft.com");
var message = _service.GetMessage();
return new OkObjectResult("Response from function with injected dependencies.");
}
}
}
```
**Whether to Supply Codefix**
Yes for 1, if possible for 2.
**Associated Documentation**
https://docs.microsoft.com/en-us/azure/azure-functions/manage-connections
**When to Suppress Analyzer Rule**
This rule should not be suppressed.
Contributor guide
Research direction
The issue names no files or tests; start by locating the analyzer entry point that inspects [Function]-decorated methods and new HttpClient expressions. Compare the warning and requested static-instance code fix with the examples, then verify the diagnostic and fix behavior against the associated Azure Functions connection-management documentation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, csharp
- Domain
- cloud, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100