请求聚合
当下游服务是返回404状态码,在返回结果中,其对应的值则为空值,
即使聚合路由中所有的下游服务都返回404状态码,聚合路由的返回结果也不会是404状态码。
Ocelot允许你声明聚合路由,这样你可以把多个正常的Routes打包并映射到一个对象来对客户端的请求进行响应。比如,你请求订单信息,订单中又包含商品信息,这里就设计到两个微服务,一个是商品服务,一个是订单服务。如果不运用聚合路由的话,对于一个订单信息,客户端可能需要请求两次服务端。实际上这会造成服务端额外的开销。这时候有了聚合路由后,你只需要请求一次聚合路由,然后聚合路由会合并订单跟商品的结果都一个对象中,并把这个对象响应给客户端。使用Ocelot的此特性可以让你很容易的实现前后端分离的架构。
为了实现Ocelot的请求功能,你需要在ocelot.json中进行如下的配置。这里我们指定了了两个正常的Routes,然后给每个Route设置一个Key属性。最后我们再Aggregates节点中的RouteKeys属性中加入我们刚刚指定的两个Key从而组成了两个Routes的聚合。当然我们还需要设置UpstreamPathTemplate匹配上游的用户请求,它的工作方式与正常的Route类似。
public class Goods{public int Id { get; set; }public string Content { get; set; }}public class Orders{public int Id { get; set; }public string Content { get; set; }}
》》服务1
namespace OService1.Controllers
{[Route("api/[controller]")][ApiController]public class GoodController : ControllerBase{ [HttpGet("{id}")]public ActionResult<string> Get(int id){var item = new Goods{Id = id,Content = $"{id}的关联的商品明细",};return JsonConvert.SerializeObject(item);}}
}
》》服务2
namespace OService1.Controllers
{[Route("api/[controller]")][ApiController]public class OrderController : ControllerBase{ [HttpGet("{id}")]public ActionResult<string> Get(int id){var item = new Orders {Id=id,Content=$"{id}的订单明细",};return JsonConvert.SerializeObject(item);}}
}
》》配置
分三个文件配置
//ocelot.good.json
{"DownstreamPathTemplate": "/api/Good/{id}","DownstreamScheme": "http","DownstreamHostAndPorts": [{"Host": "localhost","Port": 1001}],"UpstreamPathTemplate": "/good/{id}","UpstreamHttpMethod": [ "Get", "Post" ],"Key": "Good","Priority": 2}
//ocelot.order.json
{"DownstreamPathTemplate": "/api/Order/{id}","DownstreamScheme": "http","DownstreamHostAndPorts": [{"Host": "localhost","Port": 1002}],"UpstreamPathTemplate": "/order/{id}","UpstreamHttpMethod": [ "Get", "Post" ],"Key": "Order","Priority": 2}
// ocelot.all.json"Aggregates": [{"RouteKeys": ["Good","Order"],"UpstreamPathTemplate": "/GetOrderDetail/{id}"}]
或者放在一个配置文件
{"Routes": [//路由一{"DownstreamPathTemplate": "/api/Good/{id}", //下游路径"DownstreamScheme": "https", //http,https"DownstreamHostAndPorts": [{"Host": "localhost", //下游地址"Port": 1001//下游端口}],"UpstreamPathTemplate": "/good/{id}", //上游路径"UpstreamHttpMethod": [ "Get" ],"Key": "Good"},//路由二{"DownstreamPathTemplate": "/api/Order/{id}","DownstreamScheme": "https","DownstreamHostAndPorts": [{"Host": "localhost","Port": 1002}],"UpstreamPathTemplate": "/order/{id}","UpstreamHttpMethod": [ "Get" ],"Key": "Order"}],"Aggregates": [{"RouteKeys": ["Good","Order"],"UpstreamPathTemplate": "/GetOrderDetail/{id}"}],"GlobalConfiguration": {"BaseUrl": "https://localhost:1000"}
}
Ocelot将始终使用聚合请求返回内容类型application/json。还有需要注意的是聚合请求不会返回404请求。
如果两个下游都返回404状态码的话,这里聚合后的响应也不会返回404,
只会返回空的json串,拿上面的实例,如果两个下游都返回404的话,那么他的响应代码类似下面这样:
{"Good": ,"Order":
}