using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using System.Net.Http; var builder = WebApplication.CreateBuilder(args); // to build the binary dotnet publish -c Release -o ./publish // Go backend builder.Services.AddHttpClient("GoBackend", client => { client.BaseAddress = new Uri("http://localhost:8080"); client.Timeout = TimeSpan.FromSeconds(30); }); // Node frontend builder.Services.AddHttpClient("NodeFrontend", client => { client.BaseAddress = new Uri("http://localhost:3000"); client.Timeout = TimeSpan.FromSeconds(30); }); var app = builder.Build(); app.UseStaticFiles(); app.Use((Func, Task>)(async (context, next) => { var clientFactory = context.RequestServices.GetRequiredService(); var isApiRequest = context.Request.Path.StartsWithSegments("/api") || context.Request.Path.StartsWithSegments("/graphql") || context.Request.Path.StartsWithSegments("/auth") || !context.Request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase); var client = clientFactory.CreateClient(isApiRequest ? "GoBackend" : "NodeFrontend"); try { var requestUri = context.Request.Path + context.Request.QueryString; var request = new HttpRequestMessage( new HttpMethod(context.Request.Method), requestUri); foreach (var header in context.Request.Headers) { if (!request.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray())) { request.Content ??= new StreamContent(context.Request.Body); request.Content.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()); } } if (context.Request.ContentLength > 0 || context.Request.Headers.ContainsKey("Transfer-Encoding")) { request.Content = new StreamContent(context.Request.Body); } var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted); context.Response.StatusCode = (int)response.StatusCode; foreach (var header in response.Headers) { context.Response.Headers[header.Key] = header.Value.ToArray(); } foreach (var header in response.Content.Headers) { context.Response.Headers[header.Key] = header.Value.ToArray(); } context.Response.Headers.Remove("transfer-encoding"); await response.Content.CopyToAsync(context.Response.Body); } catch (HttpRequestException ex) { context.Response.StatusCode = isApiRequest ? 503 : 502; await context.Response.WriteAsync($"{(isApiRequest ? "Go API" : "Frontend")} unavailable: {ex.Message}"); } })); app.Run();