Docker Compose环境中Blazor WASM调用GraphQL容器接口的URI适配方案
问题描述
我有一个Blazor WASM前端和GraphQL后端的解决方案,两者都已容器化且能独立正常运行。对应的docker-compose.yml配置如下:
version: "3.4" name: search_and_map services: blazor_wasm: image: fdq09eca/search_and_map-blazor_wasm build: context: . dockerfile: src/NDSH.Geospatial.Demos.SearchAndMap.Blazor/src/Dockerfile ports: - 8080:80 graphql_api: image: fdq09eca/search_and_map-graphql_api build: context: . dockerfile: src/NDSH.Geospatial.Demos.SearchAndMap.Api/src/Dockerfile ports: - 51803:80
我在Blazor WASM中用以下代码向后端发送Post请求:
private async void GetAllBgsLayersFromGraphqlApi(MetadataSearchModel metadataSearchModel) { Uri graphqlApiUri = new Uri("http://search_and_map-graphql_api-1:80/graphql/"); try { HttpClient client = new HttpClient(); var queryContent = @" query { bgsLayers { recordId, fileIdentifier, relatedDataSetUuId, operatesOnTitle, wmsLayerName, wmsLayerTitle, wmsLayerAbstract, wmsGetCapabilityUrl, arcGisMapServerUrl, arcGisLayerUrl, arcGisLayerName } }"; var queryObject = new { query = queryContent }; var queryJson = JsonConvert.SerializeObject(queryObject); var request = new HttpRequestMessage { RequestUri = graphqlApiUri, Method = HttpMethod.Post, Content = new StringContent(content: queryJson, encoding: System.Text.Encoding.UTF8, mediaType: "application/json"), }; using (var response = await client.SendAsync(request)) { response.EnsureSuccessStatusCode(); string responseString = await response.Content.ReadAsStringAsync(); var obj = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, List<BgsLayer>>>>(responseString); metadataSearchModel.BgsLayers = obj!["data"]["bgsLayers"]; return; } } catch (Exception ex) { System.Console.WriteLine("calling GraphQL API ERROR!!"); System.Console.WriteLine($"[ERR] {ex.Message}"); System.Console.WriteLine($"[uri] {graphqlApiUri.AbsolutePath}"); throw; } }
但graphqlApiUri无法被正确解析,浏览器报错。本地环境用http://localhost:51803/graphql能正常运行,但在EC2实例上执行docker compose up后出现问题。请问如何正确解析URI,使其在本地和EC2环境都能正常工作?
解决方案
核心问题分析
Blazor WASM是浏览器端运行的应用,它的HTTP请求是从用户浏览器发起的,而非容器内部。你使用的search_and_map-graphql_api-1是Docker内部的服务名称,浏览器无法解析这个域名,这就是报错的根本原因。
具体解决步骤
1. 统一配置API地址
在Blazor WASM项目中通过环境配置文件管理API地址,避免硬编码:
- 本地开发环境(
appsettings.Development.json):{ "GraphqlApiSettings": { "BaseUrl": "http://localhost:51803/graphql/" } } - EC2生产环境(
appsettings.Production.json):
替换{ "GraphqlApiSettings": { "BaseUrl": "http://<EC2公网IP>:51803/graphql/" } }<EC2公网IP>为你的EC2实例实际公网IP或绑定的域名。
2. 注入配置到代码中
- 先创建配置映射类:
public class GraphqlApiSettings { public string BaseUrl { get; set; } = string.Empty; } - 在
Program.cs中注册配置服务:builder.Services.Configure<GraphqlApiSettings>(builder.Configuration.GetSection("GraphqlApiSettings")); - 在组件中通过依赖注入获取配置:
private readonly GraphqlApiSettings _apiSettings; public YourComponent(IOptions<GraphqlApiSettings> apiSettings) { _apiSettings = apiSettings.Value; }
3. 修改请求代码使用配置地址
把硬编码的URI替换为配置中的地址:
Uri graphqlApiUri = new Uri(_apiSettings.BaseUrl);
4. 本地Docker Compose优化(可选)
如果希望本地容器运行时自动读取正确地址,可在docker-compose.yml的blazor_wasm服务中添加环境变量:
blazor_wasm: # 原有配置... environment: - ASPNETCORE_ENVIRONMENT=Development - GraphqlApiSettings__BaseUrl=http://localhost:51803/graphql/
额外注意事项
- 确保EC2实例的安全组开放了51803端口,允许外部访问。
- 生产环境建议使用HTTPS,避免明文传输数据。
内容的提问来源于stack exchange,提问作者Chris LAM
相关产品推荐
相关产品推荐

