.NET Core开发实战(第25课:路由与终结点:如何规划好你的Web API)--学习笔记(下)...
25 | 路由與終結點:如何規劃好你的Web API
自定義約束實現了路由約束接口,它只有一個 Match 方法,這個方法傳入了 Http 當前的 httpContext,route,routeKey
這個 routeKey 就是我們要驗證的 key 值
后面兩個參數 RouteValueDictionary 就是當前可以獲取到的這個 routeKey 對應的傳入的值是什么值,這樣就可以驗證我們傳入的信息
routeDirection 這個枚舉的作用是當前驗證是用來驗證 URL 請求進來,驗證是否路由匹配,還是用來生成 URL,是進還是出的這樣一個定義,在不同的場景下面可能響應的邏輯是不一樣的
下面的邏輯是如果路由是進來的,也就是通過 URL 配置 action 的情況,就做一個判斷,根據 routeKey 取到當前輸入的這個值,然后判斷它是否可以轉成 long,這個其實模擬了類型驗證,比如說 long 型驗證的方式
namespace RoutingDemo.Constraints {public class MyRouteConstraint : IRouteConstraint{public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection){if (RouteDirection.IncomingRequest == routeDirection){var v = values[routeKey];if (long.TryParse(v.ToString(), out var value)){return true;}}return false;}} }RouteDirection
namespace Microsoft.AspNetCore.Routing {public enum RouteDirection{IncomingRequest = 0,UrlGeneration = 1} }接下來看一下約束是如何注入到我們系統里生效的
可以給我們的約束起一個名字 isLong,這個名字就是用來 Attribute 上面標識約束的
services.AddRouting(options => {//options.ConstraintMap.Add("MyRouteConstraint", typeof(MyRouteConstraint));options.ConstraintMap.Add("isLong", typeof(MyRouteConstraint)); });OrderController 里面也修改為 isLong
/// <summary> /// /// </summary> /// <param name="id">必須可以轉為long</param> /// <returns></returns> //[HttpGet("{id:MyRouteConstraint}")]// 這里使用了自定義的約束 [HttpGet("{id:isLong}")] //public bool OrderExist(object id) public bool OrderExist([FromRoute] string id) {return true; }啟動程序,輸入34,返回響應碼200,輸入abc,返回響應碼404,也就是自定義約束生效了
接下來講一下鏈接生成的過程
/// <summary> /// /// </summary> /// <param name="id">最大20</param> /// <param name="linkGenerator"></param> /// <returns></returns> [HttpGet("{id:max(20)}")]// 這里使用了 Max 的約束 //public bool Max(long id) public bool Max([FromRoute]long id, [FromServices]LinkGenerator linkGenerator) {// 這兩行就是分別獲取完整 Uri 和 path 的代碼// 它還有不同的重載,可以根據需要傳入不同的路由的值var path = linkGenerator.GetPathByAction(HttpContext,action: "Reque",controller: "Order",values: new { name = "abc" });// 因為下面對 name 有一個必填的約束,所以這里需要傳值var uri = linkGenerator.GetUriByAction(HttpContext,action: "Reque",controller: "Order",values: new { name = "abc" });return true; }/// <summary> /// /// </summary> /// <param name="ss">必填</param> /// <returns></returns> [HttpGet("{name:required}")]// 必填約束 public bool Reque(string name) {return true; }啟動程序,端點調試,輸入1,點擊執行,可以看到
path 的值為
/api/Order/Reque/abcuri 的值為
https://localhost:5001/api/Order/Reque/abc在定義 Controller 的時候,實際上還會做一些接口廢棄的過程,通過 [Obsolete]
/// <summary> /// /// </summary> /// <param name="ss">必填</param> /// <returns></returns> [HttpGet("{name:required}")]// 必填約束 [Obsolete] public bool Reque(string name) {return true; }我們不必直接刪除我們的接口,它還可以正常工作,但是我們可以把它標記為已廢棄,在 Swagger 上面會有體現
可以看到這個接口已經被標記為廢棄的,但是它的調用還是可以工作的
總結一下
1、Restful 不是必須的,只要約束好 Http 方法以及 URL 地址,還有 Http 響應碼,響應的 Json 格式,這些約定只要適合團隊的協作習慣就可以了,也就是說需要定義好 API 的表達契約
2、建議是把 API 都約束在特定的目錄下面,與其他功能性頁面進行隔離,比如說 /api /api 加版本號這樣子的方式
3、在廢棄 API 的過程中間,應該是間隔版本的方式廢棄,也就是說先將即將廢棄的 API 標記為已廢棄,但是它還是可以工作,間隔幾個版本之后將代碼刪除掉
到目前為止,講解了依賴注入,配置日志,中間件等必要的內容,下一節開始將進入微服務實戰的部分
總結
以上是生活随笔為你收集整理的.NET Core开发实战(第25课:路由与终结点:如何规划好你的Web API)--学习笔记(下)...的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: DotNetCore Web应用程序中的
- 下一篇: 微软 Visual Studio 201
