<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go語言版本1.22的路由增強功能

          共 2731字,需瀏覽 6分鐘

           ·

          2024-04-10 21:48

          Go 1.22對 net/http包中的路由器進行了兩項增強:方式匹配和通配符。這些特性允許你將常見的路由表示為模式,而非Go代碼。盡管這些功能簡單易解釋和使用,但想選擇成功模式的正確規(guī)則(當多個模式匹配一個請求時)依然是個挑戰(zhàn)。我們作出這些改變是為了持續(xù)讓Go成為構建生產(chǎn)系統(tǒng)的優(yōu)秀語言。我們研究了許多第三方web框架,提取出我們認為最常用的特性,并將它們集成進 net/http。然后我們通過在GitHub上與社區(qū)進行討論和問題建議,驗證了我們的選擇并改進了我們的設計。將這些特性添加到標準庫意味著許多項目少了一個依賴性。但對于當前用戶或帶有高級路由需求的程序來說,第三方Web框架仍然是一個很好的選擇。

          新增功能

          新的路由功能幾乎完全影響到了 net/http.ServeMux方法 HandleHandleFunc傳遞的模式字符串,以及頂層函數(shù) http.Handlehttp.HandleFunc。唯一的API變化是在 net/http.Request上添加了兩個新方法,用于處理通配符匹配。我們將通過一個假設的博客服務器來說明這些變化,其中每篇帖子都有一個整數(shù)標識符。請求如GET /posts/234取回ID為234的帖子。在Go 1.22之前,處理這些請求的代碼將從這樣的一行開始:

              
          1. http . Handle ( "/posts/" , handlePost )

          尾部的斜杠將所有以 /posts/開始的請求路由到 handlePost函數(shù),該函數(shù)將需要檢查HTTP方法是否為GET,提取標識符,并取回帖子。由于方法檢查并非嚴格必要以滿足請求,忽略它將是一個自然的錯誤。這將意味著像 DELETE/posts/234這樣的請求將取回帖子,這至少是令人驚訝的。而在Go 1.22中,現(xiàn)有代碼將繼續(xù)工作,或者你可以改寫成這樣:

              
          1. http . Handle ( "GET /posts/{id}" , handlePost2 )

          這個模式匹配路徑開始以 /posts/的請求并且有兩個段的GET請求將匹配到這個模式(特別是,GET也可以匹配HEAD; 其他所有的方法都僅僅匹配一次)。handlePost2這個函數(shù)不再需要檢查方法,并且可以通過在Request上使用新的 PathValue方法來編寫提取標識符字符串:

              
          1. idString := req . PathValue ( "id" )

          剩下的 handlePost2將會行為類似 handlePost,將字符串標識符轉(zhuǎn)換為整數(shù)并獲取帖子。如DELETE /posts/234 這樣的請求在沒有其他匹配模式被注冊的情況下將失敗。根據(jù)HTTP語法,一個 net/http服務器將會回復這樣的請求一個405 Method Not Allowed錯誤并在Allow頭中列出可用的方法。一個通配符可以匹配一個全部的段,就像上面的例子中的 {id},或者,如果它以 ...結(jié)束,它可以匹配路徑中所有剩余的段,就像這個模式:/files/{pathname...}。還有最后一點語法。正如我們上面展示的,以斜杠結(jié)尾的模式,像 /posts/,匹配所有以該字符串開始的路徑。要只匹配結(jié)尾有斜杠的路徑,你可以寫成 /posts/{$}。這將匹配到 /posts/但不會匹配到 /posts/posts/{234}。還有最后一點API:net/http.Request有一個 SetPathValue方法,以便標準庫之外的路由器可以通過Request.PathValue使他們自己路徑解析的結(jié)果可用。

          優(yōu)先級

          每一個HTTP路由器必須處理重疊的模式,就像 /posts/{id}/posts/latest。這兩種模式都匹配“posts/latest”路徑,但最多只能有一個處理請求。哪一個模式優(yōu)先呢?一些路由器不允許重疊;其它的使用最后注冊的模式。Go一直允許重疊,并且有選擇更長的模式的優(yōu)先級規(guī)則,不論注冊順序。保證順序不依賴很重要并且必須向后兼容,但我們需要一個比“最長的贏”更好的規(guī)則。這個規(guī)則會選擇 /post/latest而不是 /post/{id},但卻會選擇 /posts/{id}/{category}而不是 /posts/{id}。當我們選擇新的規(guī)則時,有幾點我們想要:我們想要一個可以預測的規(guī)則,這樣當你看到一系列模式注冊的時候,你可以知道哪一個模式會匹配給定路徑。如果這個規(guī)則對于模式注冊的順序沒有依賴性,那么它就是“順序不依賴”的,用戶將更容易理解和處理。因為所以這個匹配的路徑在處理程序內(nèi)部都能被看到,一個好的規(guī)則需要對于所有請求一視同仁,其他規(guī)則則可能給攻擊者提供利用程序隱藏bug的機會。最后,我們希望新規(guī)則能夠盡可能的保留現(xiàn)有的行為,以支持向后兼容性。目前, net/http的優(yōu)先級規(guī)則被定義為,“更長的元素會匹配”。換句話說,我們會比較模式中的元素總數(shù)量,包括各種元素類型,即使他們不在同級別。例如,模式 /a/b/c/a/b之間的比較,將會有 /a/b/c勝出,因為它有3個元素,而 /a/b只有2個。在新的規(guī)則下,我們依然遵循舊規(guī)定,長優(yōu)先匹配,但引入了明顯的層級關系。在進行比較的時候,我們會先看模式元素類型的數(shù)量是否有不同, 然后才看元素的總數(shù)量。所以 /a/b/c仍然會優(yōu)先匹配,因為 /a/b只有兩層, "這很直觀。然而,當涉及到帶有通配符的模式時,這種層級關系就顯得非常重要了。如 /a/{p}/c/a/b, /a/b優(yōu)先匹配,盡管總元素數(shù)量較少, 因為它包含更多的文字元素。帶有方法和通配符的新模式讓我們更有信心地使用新匹配規(guī)則,新規(guī)則會盡量匹配文本元素,而適當?shù)亟档土送ㄅ浞貎?yōu)先級。特定的元素(文本和方法)在具體的元素(通配符)之前,文本元素優(yōu)先于方法元素。在比較完所有這些情況后,我們最后才進行長度比較。這種新的優(yōu)先級規(guī)則在實踐中很容易理解和預測。

          總結(jié)

          這些新特性讓Go的內(nèi)置HTTP庫更強大,能更清晰地表達日常web編程任務。這些特性是 net/http包長期沉淀的結(jié)果,經(jīng)過了多次反復考量,包括研究web框架的API,同社區(qū)反復交流,以及我們認為對于大部分Go web編程來說是有意義的特性。如果你對這些特性有任何的反饋,歡迎在我們的issue tracker上提出。我們期待你在Go1.22版本中試用這些新功能!


          瀏覽 36
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线无码视频免费观看 | 天天干天天射av 天天天日天天天干 | 酒店偷拍无码成人网站 | 91污网站 | 午夜操逼在线 |