我是API网关的新手,有一个理解上的问题。 我也尝试在端点后面放置一系列(微)服务。
为此,我建立了一个ASP.NET Core应用程序并添加了软件包ThreeMammals Ocelot。 借助文档,我已经配置了上游和下游。 到目前为止,一切都很好。
客户端向http://mygateway:4242/s1/ {api}发出请求,例如,按预期从Service1获取JSON或XML响应。
http://mygateway:4242/s2/ {api}的行为与预期结果相同!
我的理解问题在于Service3。 当我向http://mygateway/s3/发送请求时,我得到index.html作为响应。
index.html本身通过链接标签需要CSS文件'xyz.css',并强制客户端加载文件。
<head>
<link rel="stylesheet" type="text/css" href="xyz.css">
</head>
在这种情况下,客户端发送到“ mygateway”的请求URL为http://mygateway:4242/xyz.css,而不是 http://mygateway:4242/ s3 /xyz.css,因此未显示404,因为“ mygateway”对“ xyz.css”一无所知
如何解决此路由(?)问题?
使用ocelot中间件是否可以解决此问题?还是我需要带有SinglePageApplication(SPA)的服务(Service3)的其他东西?
将SPA放置在网关后面也许根本就是不可能或错误吗? 希望您能给我一些提示,以访问网关后面的SPA或MVC网站。
感谢iBot
更新: 随附index.html的代码。我认为这很简单。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
<base href="/" />
<link rel="stylesheet" type="text/css" href="dist/xyz.css">
</head>
<body>
<div id="appContainer"></div>
<script src="dist/xyz.js" asp-append-version="true"></script>
</body>
</html>
答案 0 :(得分:2)
您的建筑设计是错误的!
首先,让我们找出这是什么API网关。
API Gateway是一种编程,它位于应用程序编程接口(API)的前面,并充当一组已定义的微服务的单一入口。
使用API网关的主要好处是,它们允许开发人员根据用例以多种方式封装应用程序的内部结构。这是因为,除了可以容纳直接请求之外,网关还可以用于调用多个后端服务并汇总结果。
好吧,名称“ API 网关”向我们表明它主要用于API服务! SPA或MVC应用程序不是后端服务。您不应将前端应用程序放在api网关后面。
API网关是所有客户端的单个入口点。 SPA是您的服务的客户端,应通过API网关调用它。如果您的应用程序具有多个客户端应用程序,则在确定多种API网关类型时,这可能是主要的枢纽,因此您可以为每个客户端应用程序的需求使用不同的外观。这种情况是一种名为“Backend for Frontend” (BFF)的模式,其中每个API网关都可以提供针对每种客户端应用类型量身定制的不同API。
如果您不想构建合适的体系结构怎么办?
http://mygateway:4242/
的客户端都将重定向到http://mygateway:4242/s3/
答案 1 :(得分:2)
有一个用于构建Api网关的开源.Net Core 3库。
该库称为 AspNetCore.ApiGateway 。
让我们说,您的后端API 具有GET终结点,如:
在Orchestrator中,如下所示设置Api(例如,气象服务)和Key(例如,预测)。
public static class ApiOrchestration
{
public static void Create(IApiOrchestrator orchestrator, IApplicationBuilder app)
{
orchestrator.AddApi("weatherservice", "http://localhost:58262/")
.AddRoute("forecast", GatewayVerb.GET, new RouteInfo { Path = "weatherforecast/forecast", ResponseType = typeof(IEnumerable<WeatherForecast>) })
.AddApi("stockservice", "http://localhost:58352/")
.AddRoute("stocks", GatewayVerb.GET, new RouteInfo { Path = "stock", ResponseType = typeof(IEnumerable<StockQuote>) });
}
}
public void ConfigureServices(IServiceCollection services)
{
.
.
//Api gateway
services.AddApiGateway();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My Api Gateway", Version = "v1" });
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
.
.
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My Api Gateway");
});
//Api gateway
app.UseApiGateway(orchestrator => ApiOrchestration.Create(orchestrator, app));
.
.
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Gateway Swagger显示如下:
要在气象服务上调用天气预报路线,
您可以按如下所示在Swagger中输入Api键和Route键:
这将在后端Weather API上达到weatherforecast / forecast端点。
答案 2 :(得分:0)
您可以尝试写<base href="/s3/" />
而不是<base href="/" />
。
但是最好在网关之前使用SPA或MVC。在大多数情况下,这取决于您将如何使用它。例如,如果您希望像域代理(例如Nginx)一样使用它,那就很有意义。