這是系列文章中的第一篇:使用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;
b -> d;
}
它描述了以下圖表:

您可以自定義節點和邊緣以多種方式顯示的方式,例如,可以標記節點和邊緣:
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以紅色顯示,帶有虛線和空三角形箭頭,
現在,我承認我的設計技巧很爛,但是我認為您可以同意這個圖表顯示的資訊比默認的要多!??--這是生成上面的圖形的定義,請記住,您可以使用在線編輯來可視化和播放顯示,
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應用程式中的端點路由表示為有向圖,我描述了端點圖中不同節點和邊緣之間的差異,并調整了圖形的顯示以更好地表示這些差異,在后面的文章中,我將展示如何為應用程式生成自己的端點圖,如何自定義顯示,以及如何做的不僅僅是查看圖形,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/1641.html
標籤:.NET Core
