Reputation: 536
I'm currently experimenting with .NET Aspire. According to docs, Aspire is used to streamline connections and communication between services in applications. One of the features that Aspire offers is the ease of communications between services, by giving each a special name that can be resolved via them, removing the need to manually set the ports and match the addresses for making services connect.
In the .NET Aspire Quickstart Documentation, is it explained that you can set custom names to your projects in the AppHost
Project's Program.cs
file like this:
var builder = DistributedApplication.CreateBuilder (args);
var usersApi = builder
.AddProject<Projects.Bargeh_Users_API> ("usersapi"); // Setting the name "usersapi" to the project
builder.AddProject<Projects.Bargeh_Main_Wapp> ("bargehmainwapp")
.WithReference (usersApi)
.WithReference (smsApi)
.WithLaunchProfile ("https");
builder.Build ().Run ();
Again from the documentation, you can add this code in the project that wants to have access to the other service and let Aspire know that you need that service and resolve that URL for you:
builder.Services.AddHttpClient<UsersApiHttpClientProvider>(
static client=> client.BaseAddress = new("http://usersapi"));
Then, you can inject UsersApiHttpClientProvider
wherever you want and make use of it.
This approach works, but only for accessing APIs that are open to normal HTTP requests. The problem is, that the UsersApi
that I'm using is not a REST API, but it's a GRPC service. I can connect to the API and send requests to it, but I'm unable to send real GRPC requests.
My question is, how can I make my client projects (a Blazor Web App in this case) connect to my backend GRPC Services using Grpc.Net
packages, while the connection between them is established by .NET Aspire?
Upvotes: 5
Views: 1585
Reputation: 136
Code of AppHost for me looks like following:
using System.Net.Sockets;
var builder = DistributedApplication.CreateBuilder(args);
var server = builder.AddProject<Projects.Server>("server");
var apiservice = builder.AddProject<Projects.AspireHost_ApiService>("apiservice")
.WithReference(server);
builder.AddProject<Projects.AspireHost_Web>("webfrontend")
.WithReference(apiservice);
builder.Build().Run();
Here Projects.Server
is an application with GRPC server.
A client application, in my case AspireHost_ApiService
, should reference Grpc.Net.ClientFactory
package
Then adding of a GRPC client should look like:
builder.Services
.AddGrpcClient<ServerService.ServerServiceClient>(
options =>
{
options.Address = new Uri("http://server");
}
);
And usage might look like:
api.MapGet(
"/",
async (ServerService.ServerServiceClient client) =>
{
...
}
);
That works at least from Aspire Preview 6 where I actually tested it.
Upvotes: 4
Reputation: 925
The answer from Drone is factual but it isn't the correct approach. You don't need to look at the environment variables that Aspire creates, leave that to Aspire.
Just do something like this to configure your gRPC client:
builder.Services.AddGrpcClient<UsersApiHttpClientProvider>(
static client=> client.BaseAddress = new("https://usersapi"))
.ConfigurePrimaryHttpMessageHandler(
() => new GrpcWebHandler(new HttpClientHandler()));
That is similar to the way you were configuring an http client, the key differences are:
Upvotes: 3