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