いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-345 (Go 1.22で http.ServeMux にパターンマッチング機能が追加される)(gotip, net/http)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。忘れない内にメモメモ。。。

Go 1.22 で、http.ServeMux にパターンマッチング機能が追加されるみたいですね。

以下で知りました。

eli.thegreenplace.net

Goの標準ライブラリらしく、シンプルなパターンマッチング機能が搭載される感じです。

シンプルなWebアプリならこれで充分です。

多機能が欲しい場合は gorilla/muxchi などを使うって住み分けになりそう。

私は chi をよく使ってますね。

標準ライブラリに機能追加されるのはとても嬉しい。多分、みんな欲しかった機能じゃないでしょうか。

試してみる

Go 1.22 は 2023-10-20 時点ではリリースされていませんので、gotip を使います。

$ go install golang.org/dl/gotip@latest
$ gotip download
$ gotip version
go version devel go1.22-3754ca0 Fri Oct 20 00:01:44 2023 +0000 linux/amd64

$ mkdir std-router; cd $_
$ gotip mod init std-router
$ cat go.mod
module std-router

go 1.22

んで、以下のようなプログラムを用意。

package main

import (
        "fmt"
        "net/http"
)

func main() {
        mux := http.NewServeMux()

        mux.HandleFunc("GET /aaa/", func(w http.ResponseWriter, r *http.Request) {
                fmt.Fprintf(w, "%s\n", "helloworld")
        })

        mux.HandleFunc("GET /name/{name}/", func(w http.ResponseWriter, r *http.Request) {
                name := r.PathValue("name")
                fmt.Fprintf(w, "hello %s\n", name)
        })

        http.ListenAndServe(":8090", mux)
}

HandleFunc の最初の引数のところに GET /aaa/ としています。

これでGETメソッドのみが対象となります。

2つ目の HandleFunc にて GET /name/{name}/ としていますね。

これが追加されたパターンマッチングです。値は r.PathValue() で取得しています。

$ gotip doc net/http.request.pathvalue
package http // import "net/http"

func (r *Request) PathValue(name string) string
    PathValue returns the value for the named path wildcard in the ServeMux
    pattern that matched the request. It returns the empty string if the request
    was not matched against a pattern or there is no such wildcard in the
    pattern.

正規表現の指定とかは出来ません。その場合は gorilla/muxchi とかを使う感じですね。

実行してみます。

$ curl -X GET http://localhost:8090/aaa/
helloworld

$ curl -X GET http://localhost:8090/name/world/
hello world

$ curl -X GET http://localhost:8090/name/12345/
hello 12345

$ curl -X POST http://localhost:8090/name/12345/
Method Not Allowed

$ curl -X GET http://localhost:8090/name/12345
<a href="/name/12345/">Moved Permanently</a>.

ちなみに chi だと、こんな感じ。

package main

import (
        "fmt"
        "net/http"

        "github.com/go-chi/chi/v5"
        "github.com/go-chi/chi/v5/middleware"
)

func main() {
        r := chi.NewRouter()

        r.Use(middleware.Logger)

        r.Get("/aaa/", func(w http.ResponseWriter, r *http.Request) {
                fmt.Fprintf(w, "%s\n", "helloworld")
        })

        r.Get("/name/{name:[a-z]+}/", func(w http.ResponseWriter, r *http.Request) {
                name := chi.URLParam(r, "name")
                fmt.Fprintf(w, "hello %s\n", name)
        })

        http.ListenAndServe(":8090", r)
}

参考情報

Goのおすすめ書籍

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。