Description
Problem
The CreateHttpClient(this DistributedApplication app, string resourceName, string? endpointName = null)
extension method on DistributedApplicationHostingTestingExtensions
in Aspire.Hosting.Testing
defaults to creating a client for the endpoint named "http" if an endpoint name is not specified, even if the specified resource has an "https" endpoint.
This can lead to confusion as ASP.NET Core project resources typically have both an "http" and "https" endpoint by default, inferred from the project's launchSettings.json file which by default specifies both an "http" and "https" address in the "https" launch profile, which is the default launch profile when launching via an Aspire AppHost project.
This behavior doesn't align with the default runtime behavior during the dev inner-loop, where service discovery will prefer the "https" endpoint address if a service address like https+http://apiservice
is specified, as it is in the Aspire project templates.
Another point of confusion can be that the Aspire starter template has a frontend Blazor web project that configures the HTTPS redirection middleware, and an API service project that doesn't configure the HTTPS redirect middleware. So in the default test scenario the following occurs:
- The AppHost project targeted by the test is launched by the
IDistributedApplicationTestingBuilder
using the first launch profile in the AppHost project's launchSettings.json file, which is the "https" profile. - The API project is started by the AppHost using the "https" profile, resulting in both an HTTP and HTTPS endpoint for the API project resource
- The web frontend project is started by the AppHost using the "https" profile, resulting in both an HTTP and HTTPS endpoint for the API project
- The test creates an
HttpClient
instance for the API service project by callingapp.CreateHttpClient("apiservice")
, resulting in a client pointed at the API project's HTTP endpoint - The test makes a request to the HTTP endpoint of the API services project which is completed over HTTP (no redirection)
- The test creates an
HttpClient
instance for the web frontend project by callingapp.CreateHttpClient("webfrontend")
, result in a client pointed at the API project's HTTP endpoint - The test makes a request to the HTTP endpoint of the web frontend project which is redirected to the HTTPS endpoint. If the ASP.NET Core HTTPS developer certificate is not trusted in the test environment, the call fails due to a certificate error and the test fails.
Workaround
Tests can work avoid this confusion by specifying which endpoint they want the HttpClient
instance configured to use, e.g. app.CreateHttpClient("apiservice", "https")
.
Potential Resolution
We might want to consider adding an overload for CreateHttpClient
that accepts a Uri
and uses the same service discovery-based logic that resolves addresses at runtime when a project resource like the web frontend uses IHttpClientFactory
with service discovery enabled to address another resource. That way, the way clients are created in tests could more closely match the way they're created in projects themselves, e.g. app.CreateHttpClient(new Uri("https://apiservice"))
, or app.CreateHttpClient(new Uri("https+http://apiservice"))
.
/Cc @ReubenBond