這是系列文章中的第一篇:使用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應用程序中的端點路由表示爲有向圖。我描述了端點圖中不一樣節點和邊緣之間的差別,並調整了圖形的顯示以更好地表示這些差別。在後面的文章中,我將展現如何爲應用程序生成本身的端點圖,如何自定義顯示,以及如何作的不只僅是查看圖形。