这是系列文章中的第一篇:使用GraphvizOnline可视化ASP.NETCore3.0终结点。.javascript
做者:依乐祝
原文:https://andrewlock.net/visualizing-asp-net-core-endpoints-using-graphvizonline-and-the-dot-language/
译文:http://www.javashuo.com/article/p-pclzblon-ne.htmlhtml
在这篇文章中,我将展现如何在ASP.NETCore3.0应用程序中使用GraphvizOnline服务。这使您能够建立以下所示的图表,这些图表描述了应用程序中的全部端点:java
GraphvizOnline是一个GitHub上的开源项目,它为DOT图形描述语言 提供了一个在线可视化工具。这是一种简单的语言,它容许您定义各类类型的图形,它将节点与边链接起来。node
例如,一个基本的无向图能够定义为git
graph MyGraph { a -- b -- c; b -- d; }
它描述了如下图表:github
每一个节点都有一个名称(a
, b
, c
, d
),而且--
定义节点之间的边缘。边定义节点之间的链接,但它们没有方向(所以名称,无向【undirected】).web
固然,你也能够定义一个有向图,其中边是有方向的。对于有向边,使用->
而不是--
。例如:api
digraph MyGraph { a -> b -> c; b -> d; }
它描述了如下图表:app
您能够自定义节点和边缘以多种方式显示的方式。例如,能够标记节点和边缘:webapp
digraph MySimpleGraph { // The label attribute can be used to change the label of a node... a [label="Foo"]; b [label="Bar"]; // ... or an edge a -> b [label="Baz"]; }
你可使用DOT图形描述语言作更多的事情,这正是咱们如今所须要的。那么,这如何应用于ASP.NET Core应用程序呢?
ASP.NETCore中的终结点路由系统经过建立端点URL段的有向图来有效地工做。而后将传入的请求与图进行匹配(一次一个段),以肯定要执行的终结点。
例如,如下简单有向图表示ASP.NET Core3.0 RazorPages 默认应用程序模板中的终结点(dotnet new webapp
),其中包含三个Razor页面:Index.cshtml, Error.cshtml和Privacy.cshtml:
digraph DFA { 1 [label="/Error/"] 2 [label="/Index/"] 3 [label="/Privacy/"] 4 -> 1 [label="/Error"] 4 -> 2 [label="/Index"] 4 -> 3 [label="/Privacy"] 4 [label="/"] }
其中描述为以下图表:
.
在上面的DOT文件中,节点被赋予顺序的整数名,
1
,2
,3
等,并使用端点名称进行标记。这是ASP.NET Core用于表示终结点图的格式。
对于Razor页面,路由很是简单,因此图很是明显。ASP.NET Core WebAPI应用程序生成了一个更有趣的图表。例如,下面显示的ASP.NET Core 2.0默认模板中包含的ValuesController
。它使用多个HTTP谓词,以及稍微复杂的URL结构:
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() => new string[] { "value1", "value2" }; // GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) => "value"; // POST api/values [HttpPost] public void Post([FromBody] string value) { } // PUT api/values/5 [HttpPut("{id}")] public void Put(int id, [FromBody] string value) { } // DELETE api/values/5 [HttpDelete("{id}")] public void Delete(int id) { } }
为了更好地度量,我还添加了一个基本的健康检查端点。UseEndpoints()
:
app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/healthz"); endpoints.MapControllers(); });
此应用程序生成如下图表:
digraph DFA { 1 [label="/healthz/"] 2 [label="/api/Values/{...}/ HTTP: GET"] 3 [label="/api/Values/{...}/ HTTP: PUT"] 4 [label="/api/Values/{...}/ HTTP: DELETE"] 5 [label="/api/Values/{...}/ HTTP: *"] 6 -> 2 [label="HTTP: GET"] 6 -> 3 [label="HTTP: PUT"] 6 -> 4 [label="HTTP: DELETE"] 6 -> 5 [label="HTTP: *"] 6 [label="/api/Values/{...}/"] 7 [label="/api/Values/ HTTP: GET"] 8 [label="/api/Values/ HTTP: POST"] 9 [label="/api/Values/ HTTP: *"] 10 -> 6 [label="/*"] 10 -> 7 [label="HTTP: GET"] 10 -> 8 [label="HTTP: POST"] 10 -> 9 [label="HTTP: *"] 10 [label="/api/Values/"] 11 -> 10 [label="/Values"] 11 [label="/api/"] 12 -> 1 [label="/healthz"] 12 -> 11 [label="/api"] 12 [label="/"] }
表现为以下图表:
在这个图中还有不少事情要作,由于咱们如今有了可变的路由参数值(路由模板中的{id}
,在图中显示为{...}
)和HTTP动词约束(GET
/PUT
/POST
等等)
当我第一次看到这个图表时,我很难理解它。每一个节点都是终结点吗?固然不是,如/api/
不该该产生响应。那这个呢?至于HTTP: *
端点呢,它们会产生响应吗?
为了进一步了解,我查阅了能够生成这些图的ASP.NET Core中的代码,但它有点复杂,不幸的是,因为大量使用
internal
类。我将在稍后的文章中探讨这些代码。
为了更好地理解端点图,咱们须要了解并不是全部的节点都是相同的。在下一节中,咱们将深刻研究这个简单图中的不一样类型的节点,而后研究一个更好的图形表示(至少在我看来!)
图中的每一个节点都与给定的“深度”相关联。这是应该已经匹配的URL段数。例如,/api/Values/
节点的深度为2-它要求空段/
和/api
段已经匹配。
当请求到达EndpointRoutingMiddleware
(由UseRouting()
添加)时,将传入的请求URL与此图进行比较。试图从树梢的根节点开始,经过图表找到一条路径。URL段与图中的边进行增量匹配,并在图中遍历一条路径,直到整个请求URL匹配为止。
每一个节点(由在ASP.NET Core中的DfaNode
中)有几个属性。咱们目前感兴趣的属性是:
Matches
*这是与该节点相关联的Endpoint
(S)。若是经过路由匹配此节点,则这是将被选择用于执行的Endpoint
。Literals
这些是链接节点的边缘。若是DfaNode
有Literals
,它具备能够进一步遍历以到达其余节点的文字段。例如,/api/
节点包含一个有/Values
值的Literal
,则指向/api/Values
节点。PolicyEdges
这些边缘是基于URL之外的约束进行匹配的。例如,图中基于动词的边,如HTTP: GET
,是策略的边缘,指的是不一样的DfaNode
.Parameters
若是节点具备支持路由参数的边缘(例如,{id}
), Parameters
指向处理匹配参数的节点。这在图中是用/*
边表示的。.还有一个附加的属性,
CatchAll
,这在某些图形中是相关的,但我如今将忽略它,由于咱们的API图并不须要它。
基于这些特性,咱们能够经过使用DOT语言的其余特性,如形状、颜色、线型和箭头:
上图中添加了如下内容:
Endpoint
都以默认样式显示,即黑色气泡。Matches
的显示为填充的棕色盒子。这些节点具备Endpoint
,这能够产生响应。对于上面的API示例,这适用于已选择谓词的节点以及健康检查端点。Parameters
边缘(/*
)以蓝色显示,使用菱形箭头。PolicyEdges
以红色显示,带有虚线和空三角形箭头。如今,我认可个人设计技巧很烂,可是我认为您能够赞成这个图表显示的信息比默认的要多!🙂--这是生成上面的图形的定义,请记住,您可使用在线编辑来可视化和播放显示。
digraph DFA { 1 [label="/healthz/" shape=box style=filled color="brown" fontcolor="white"] 2 [label="/api/Values/{...}/ HTTP: GET" shape=box style=filled color="brown" fontcolor="white"] 3 [label="/api/Values/{...}/ HTTP: PUT" shape=box style=filled color="brown" fontcolor="white"] 4 [label="/api/Values/{...}/ HTTP: DELETE" shape=box style=filled color="brown" fontcolor="white"] 5 [label="/api/Values/{...}/ HTTP: *" shape=box style=filled color="brown" fontcolor="white"] 6 -> 2 [label="HTTP: GET" color="red" style=dashed arrowhead=open] 6 -> 3 [label="HTTP: PUT" color="red" style=dashed arrowhead=open] 6 -> 4 [label="HTTP: DELETE" color="red" style=dashed arrowhead=open] 6 -> 5 [label="HTTP: *" color="red" style=dashed arrowhead=open] 6 [label="/api/Values/{...}/"] 7 [label="/api/Values/ HTTP: GET" shape=box style=filled color="brown" fontcolor="white"] 8 [label="/api/Values/ HTTP: POST" shape=box style=filled color="brown" fontcolor="white"] 9 [label="/api/Values/ HTTP: *" shape=box style=filled color="brown" fontcolor="white"] 10 -> 6 [label="/*" arrowhead=diamond color="blue"] 10 -> 7 [label="HTTP: GET" color="red" style=dashed arrowhead=open] 10 -> 8 [label="HTTP: POST" color="red" style=dashed arrowhead=open] 10 -> 9 [label="HTTP: *" color="red" style=dashed arrowhead=open] 10 [label="/api/Values/"] 11 -> 10 [label="/Values"] 11 [label="/api/"] 12 -> 1 [label="/healthz"] 12 -> 11 [label="/api"] 12 [label="/"] }
注意
"HTTP: *"
节点与端点关联,即便您可能不指望它,由于它们返回405 Method Not Allowed
.
在下一篇文章中,我将展现如何自动为本身的ASP.NET Core应用程序生成端点图。
在这篇文章中,我介绍了用于描述图形的DOT语言,并展现了如何使用在线编辑从图表中建立图像。而后,我展现了如何将ASP.NETCore 3.x应用程序中的端点路由表示为有向图。我描述了端点图中不一样节点和边缘之间的差别,并调整了图形的显示以更好地表示这些差别。在后面的文章中,我将展现如何为应用程序生成本身的端点图,如何自定义显示,以及如何作的不只仅是查看图形。