[译]使用DOT语言和GraphvizOnline来可视化你的ASP.NETCore3.0终结点01
这是系列文章中的第一篇:使用GraphvizOnline可视化ASP.NETCore3.0终结点。.
- 第1部分-使用DOT语言来可视化你的ASP.NETCore3.0终结点(本文)
- 第2部分-向ASP.NET Core应用程序添加终结点图
- 第3部分-使用ImpromptuInterface创建一个自定义的DfaGraphWriter,以便于反射
作者:依乐祝
原文:https://andrewlock.net/visualizing-asp-net-core-endpoints-using-graphvizonline-and-the-dot-language/
译文:https://www.cnblogs.com/yilezhu/p/13301981.html
在这篇文章中,我将展示如何在ASP.NETCore3.0应用程序中使用GraphvizOnline服务。这使您可以创建如下所示的图表,这些图表描述了应用程序中的所有端点:

用GraphvizOnline和DOT语言绘制图形
GraphvizOnline是一个GitHub上的开源项目,它为DOT图形描述语言 提供了一个在线可视化工具。这是一种简单的语言,它允许您定义各种类型的图形,它将节点与边连接起来。
例如,一个基本的无向图可以定义为
graph MyGraph {
a -- b -- c;
b -- d;
}
它描述了以下图表:

每个节点都有一个名称(a, b, c, d),并且--定义节点之间的边缘。边定义节点之间的连接,但它们没有方向(因此名称,无向【undirected】).
当然,你也可以定义一个有向图,其中边是有方向的。对于有向边,使用->而不是--。例如:
digraph MyGraph {
a -> b -> c;
d -> b;
}
它描述了以下图表:

您可以自定义节点和边缘以多种方式显示的方式。例如,可以标记节点和边缘:
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.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以红色显示,带有虚线和空三角形箭头。
现在,我承认我的设计技巧很烂,但是我认为您可以同意这个图表显示的信息比默认的要多!
[译]使用DOT语言和GraphvizOnline来可视化你的ASP.NETCore3.0终结点01的更多相关文章
- 使用DOT语言和Graphviz绘图(翻译)
Casa Taloyum About Me Blog Archives 使用DOT语言和Graphviz绘图(翻译) Date Wed 26 November 2014 Tags graphviz / ...
- 大数据工具比较:R 语言和 Spark 谁更胜一筹?
本文有两重目的,一是在性能方面快速对比下R语言和Spark,二是想向大家介绍下Spark的机器学习库 背景介绍 由于R语言本身是单线程的,所以可能从性能方面对比Spark和R并不是很明智的做法.即使这 ...
- 聊聊C语言和ABAP
这个公众号之前的文章,分享的都是Jerry和SAP成都研究院的同事在工作中学到的一些知识和感受.而今天这篇文章,写作的由来是因为最近我又参与了SAP成都数字创新空间应聘者的面试,和一些朋友聊了一些关于 ...
- OWL本体语言和Protege本体编辑器
OWL本体语言和Protege本体编辑器 演讲稿原作者:Wala Abdulaziz译者:Wu Di (pimgeek)转载.编辑:Tan Liwei原文发布日期:2013年6月5号原文链接:http ...
- C语言和C++中动态申请内存
在C语言和C++的动态内存的使用方法是不同的,在C语言中要使用动态内存要包含一个头文件即 #include<malloc.h> 或者是#include<stdlib.h> ...
- C语言和C++篇
C语言和C++篇 基本上所有主流的编程语言都有String的标准库,因为字符串操作是我们每个程序员几乎每天都要遇到的.想想我们至今的代码,到底生成和使用了多少String!标题上所罗列的语言,可以看成 ...
- c语言和java的区别
今晚读了一下c程序设计语言,这是一本经典书籍,发现C语言和java有很多是相同的,毕竟java是由c语言进化来的. 我大概从我自己的思考来谈谈不同点 1.c语言是面向过程,主要单位是函数,变量和函数的 ...
- CHENGDU1-Python编程语言和PEP8规范
CHENGDU1-Python编程语言和PEP8规范 PEP8规范6条? 答:PEP8规范说白了就是一种规范,可以遵守,也可以不遵守,遵守PEP8可以让代码的可读性更高. 代码编排:---缩进,4个空 ...
- 从C,C++,JAVA和C#看String库的发展(一)----C语言和C++篇
转自: http://www.cnblogs.com/wenjiang/p/3266305.html 基本上所有主流的编程语言都有String的标准库,因为字符串操作是我们每个程序员几乎每天都要遇到的 ...
随机推荐
- cb32a_c++_STL_算法_查找算法_(5)adjacent_find
cb32a_c++_STL_算法_查找算法_(5)adjacent_findadjacent_find(b,e),b,begin(),e,end()adjacent_find(b,e,p),p-par ...
- 05 . Prometheus监控Nginx
List CentOS7.3 prometheus-2.2.1.linux-amd64.tar.gz nginx-module-vts 节点名 IP 软件版本 硬件 网络 说明 Prometheus ...
- SpringBoot中注入ApplicationContext对象的三种方式
[本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 在项目中,我们可 ...
- php - 如何解决CURL错误( 7 ): 无法连接到主机?
php - 如何解决CURL错误( 7 ): 无法连接到主机? 1. 问题描述 调用第三方接口,本地调用一切ok,线上调用失败! 本地通过curLRequest()方法调用第三方接口时,curl_er ...
- Scala创建SparkStreaming获取Kafka数据代码过程
正文 首先打开spark官网,找一个自己用版本我选的是1.6.3的,然后进入SparkStreaming ,通过搜索这个位置找到Kafka, 点击过去会找到一段Scala的代码 import or ...
- Android Studio 插件 ADBWifi 无线调试真机
长话短说,步骤如下 Android Studio 安装插件 ADB Wifi.这一步可以选择AS->Settings->Plugins->Market搜索:或者可以选择去插件官网下载 ...
- yum本地源创建
1 安装yum-utils包,yum-utils可以将需要的包下载在本地,安装后可以使用yumdownloader yum -y install yum-utils* 2 建立目录/yum/yum ...
- 全栈的自我修养: 001环境搭建 (使用Vue,Spring Boot,Flask,Django 完成Vue前后端分离开发)
全栈的自我修养: 环境搭建 Not all those who wander are lost. 彷徨者并非都迷失方向. Table of Contents @ 目录 前言 环境准备 nodejs v ...
- 深入探究ASP.NET Core异常处理中间件
前言 全局异常处理是我们编程过程中不可或缺的重要环节.有了全局异常处理机制给我们带来了很多便捷,首先我们不用满屏幕处理程序可能出现的异常,其次我们可以对异常进行统一的处理,比如收集异常信息或者 ...
- 去除List集合中的重复值(四种好用的方法)(基本数据类型可用)
最近项目中需要对list集合中的重复值进行处理,大部分是采用两种方法,一种是用遍历list集合判断后赋给另一个list集合,一种是用赋给set集合再返回给list集合. 但是赋给set集合后,由于se ...