1. 程式人生 > >[譯]使用DOT語言和GraphvizOnline來視覺化你的ASP.NETCore3.0終結點01

[譯]使用DOT語言和GraphvizOnline來視覺化你的ASP.NETCore3.0終結點01

這是系列文章中的第一篇:使用GraphvizOnline視覺化ASP.NETCore3.0終結點。. 1. 第1部分-使用DOT語言來視覺化你的ASP.NETCore3.0終結點(本文) 2. 第2部分-向ASP.NET Core應用程式新增終結點圖 3. 第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](https://dreampuf.github.io/GraphvizOnline)服務。這使您可以建立如下所示的圖表,這些圖表描述了應用程式中的所有端點: ![An example endpoint routing graph](https://img2020.cnblogs.com/blog/1377250/202007/1377250-20200714214912871-1523655150.png) ## 用GraphvizOnline和DOT語言繪製圖形 [GraphvizOnline](https://dreampuf.github.io/GraphvizOnline)是一個GitHub上的[開源專案](https://github.com/dreampuf/GraphvizOnline),它為[DOT圖形描述語言](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) 提供了一個線上視覺化工具。這是一種簡單的語言,它允許您定義各種型別的圖形,它將節點與邊連線起來。 例如,一個基本的*無向圖*可以定義為 ```javascript graph MyGraph { a -- b -- c; b -- d; } ``` 它描述了以下圖表: ![A simple undirected graph](https://img2020.cnblogs.com/blog/1377250/202007/1377250-20200714214913827-1107720432.png) 每個節點都有一個名稱(`a`, `b`, `c`, `d`),並且`--`定義節點之間的邊緣。邊定義節點之間的連線,但它們沒有方向(因此名稱,*無向【undirected】*). 當然,你也可以定義一個*有向*圖,其中邊是有方向的。對於有向邊,使用`->`而不是`--`。例如: ```javascript digraph MyGraph { a -> b -> c; d -> b; } ``` 它描述了以下圖表: ![A simple directed graph](https://img2020.cnblogs.com/blog/1377250/202007/1377250-20200714214913617-645854220.png) 您可以自定義節點和邊緣以多種方式顯示的方式。例如,可以標記節點和邊緣: ```javascript 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"]; } ``` ![A labelled graph](https://img2020.cnblogs.com/blog/1377250/202007/1377250-20200714214913386-1984742219.png) 你可以使用[DOT圖形描述語言](https://en.wikipedia.org/wiki/DOT_(graph_description_language))做[更多](https://www.graphviz.org/doc/info/attrs.html)的事情,這正是我們現在所需要的。那麼,這如何應用於ASP.NET Core應用程式呢? ## 使用有向圖來視覺化ASP.NET Core終結點 ASP.NETCore中的終結點路由系統通過建立端點URL段的有向圖來有效地工作。然後將傳入的請求與圖進行匹配(一次一個段),以確定要執行的終結點。 例如,以下簡單有向圖表示ASP.NET Core3.0 RazorPages 預設應用程式模板中的終結點(`dotnet new webapp`),其中包含三個Razor頁面:*Index.cshtml*, *Error.cshtml*和*Privacy.cshtml*: ```javascript 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="/"] } ``` 其中描述為如下圖表: ![A basic Razor Pages application](https://img2020.cnblogs.com/blog/1377250/202007/1377250-20200714214913129-2133100582.png). > 在上面的DOT檔案中,節點被賦予順序的整數名,`1`, `2`, `3`等,並使用端點名稱進行標記。這是ASP.NET Core用於表示終結點圖的格式。 對於Razor頁面,路由非常簡單,所以圖非常明顯。ASP.NET Core WebAPI應用程式生成了一個更有趣的圖表。例如,下面顯示的ASP.NET Core 2.0預設模板中包含的`ValuesController`。它使用多個HTTP謂詞,以及稍微複雜的URL結構: ```csharp [Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult> Get() => new string[] { "value1", "value2" }; // GET api/values/5 [HttpGet("{id}")] public ActionResult 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()`: ```csharp app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/healthz"); endpoints.MapControllers(); }); ``` 此應用程式生成以下圖表: ```javascript 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="/"] } ``` 表現為如下圖表: ![A ValuesController endpoint routing application](https://img2020.cnblogs.com/blog/1377250/202007/1377250-20200714214912871-1523655150.png) 在這個圖中還有很多事情要做,因為我們現在有了可變的路由引數值(路由模板中的`{id}`,在圖中顯示為`{...}`)和HTTP動詞約束(`GET`/`PUT`/`POST`等等) 當我第一次看到這個圖表時,我很難理解它。每個節點都是終結點嗎?當然不是,如`/api/`不應該產生響應。那這個呢?至於`HTTP: *`端點呢,它們會產生響應嗎? > 為了進一步瞭解,我查閱了[可以生成這些圖的ASP.NET Core中的程式碼](https://github.com/dotnet/aspnetcore/blob/master/src/Http/Routing/src/Matching/DfaMatcherBuilder.cs),但它有點複雜,不幸的是,由於大量使用`internal`類。我將在稍後的文章中探討這些程式碼。 為了更好地理解端點圖,我們需要了解並非所有的節點都是相同的。在下一節中,我們將深入研究這個簡單圖中的不同型別的節點,然後研究一個更好的圖形表示(至少在我看來!) ## 瞭解不同型別的節點。 圖中的每個節點都與給定的“深度”相關聯。這是應該已經匹配的URL段數。例如,`/api/Values/`節點的深度為2-它要求空段`/`和`/api`段已經匹配。 當請求到達`EndpointRoutingMiddleware`(由`UseRouting()`新增)時,將傳入的請求URL與此圖進行比較。試圖從樹梢的根節點開始,通過圖表找到一條路徑。URL段與圖中的邊進行增量匹配,並在圖中遍歷一條路徑,直到整個請求URL匹配為止。 每個節點(由[在ASP.NET Core中的`DfaNode`中](https://github.com/dotnet/aspnetcore/blob/cc3d47f5501cdfae3e5b5be509ef2c0fb8cca069/src/Http/Routing/src/Matching/DfaNode.cs))有幾個屬性。我們目前感興趣的屬性是: - `Matches`*這是與該節點相關聯的`Endpoint`(S)。如果通過路由匹配此節點,則這是將被選擇用於執行的`Endpoint`。 - `Literals`這些是連線節點的邊緣。如果`DfaNode`有`Literals`,它具有可以進一步遍歷以到達其他節點的文欄位。例如,`/api/`節點包含一個有`/Values`值的`Literal`,則指向`/api/Values`節點。 - `PolicyEdges`這些邊緣是基於URL以外的約束進行匹配的。例如,圖中基於動詞的邊,如`HTTP: GET`,是策略的邊緣,指的是不同的`DfaNode`. - `Parameters`如果節點具有支援路由引數的邊緣(例如,`{id}`), `Parameters`指向處理匹配引數的節點。這在圖中是用`/*`邊表示的。. > 還有一個附加的屬性,`CatchAll`,這在某些圖形中是相關的,但我現在將忽略它,因為我們的API圖並不需要它。 基於這些特性,我們可以通過使用[DOT語言的其他特性](https://www.graphviz.org/doc/info/attrs.html),如形狀、顏色、線型和箭頭: ![A ValuesController endpoint routing application with different styling](https://img2020.cnblogs.com/blog/1377250/202007/1377250-20200714214912405-1570561611.png) 上圖中添加了以下內容: - 沒有任何關聯的節點`Endpoint`都以預設樣式顯示,即黑色氣泡。 - 有`Matches`的顯示為填充的棕色盒子。這些節點具有`Endpoint`,這可以產生響應。對於上面的API示例,這適用於已選擇謂詞的節點以及健康檢查端點。 - 文欄位邊緣顯示為預設的黑色邊緣,帶有一個填充箭頭。 - `Parameters`邊緣(`/*`)以藍色顯示,使用菱形箭頭。 - `PolicyEdges`以紅色顯示,帶有虛線和空三角形箭頭。 現在,我承認我的設計技巧很爛,但是我認為您可以同意這個圖表顯示的資訊比預設的要多!