GolangでURLルーターをつくった.pdf

 GolangでURLルーターをつくった.pdf

0c9a69560f916778b569086d792680bb?s=128

bmf_san

May 07, 2020
Tweet

Transcript

  1. GolangでHTTP Routerをつくった @bmf_san

  2. https://speakerdeck.com/bmf_san/urlruteinguwotukuruepisodo1

  3. 続編にして完結編

  4. ⽬次 ・HTTP Routerの仕組み ・データ構造 ・Golangでの実装

  5. Github https://github.com/bmf-san/goblin

  6. 1 HTTP Routerの仕組み

  7. HTTP Router is 何? ・リクエストされたURLやHTTP Methodに応じて、 処理の実⾏を制御するアプリケーション ・URLとアプリケーションの処理を結びつける

  8. 処理のイメージ

  9. パターン Routerが解釈するルーティングのパターン ・静的なルーティング →/foo/barが/foo/barに⼀致 ・動的なルーティング →/foo/bar/123が/foo/bar/:idに⼀致

  10. 2 データ構造

  11. データ構造を考える ・Router≒⽂字列マッチング ・URLの階層構造と相性が良いデータ構造 →⽊構造

  12. ⽊構造

  13. トライ⽊(プレフィックス⽊) ・⽂字列の集合を扱う⽊構造の⼀種 ・ざっくりいうと、⽂字列を探索しやすいように⽊に 格納したやつ ・ex. サジェスト、IPアドレス探索、形態素解析とか に応⽤が⾒られる

  14. トライ⽊を知る ・https://www.cs.usfca.edu/~galles/visualization/ Trie.html →アルゴリズムのビジュアライズ ・https://github.com/bmf-san/road-to-algorithm- master/tree/master/data_structures/tree/trie →参照実装かいた

  15. オレオレトライ⽊ ・ルーティングの定義を元にオレオレトライ⽊をつく る(これが結構試⾏錯誤した..) ・トライ⽊の定義に当てはまるのかちょっと⾃信ない けど多分トライ⽊、いやギリトライ⽊だと思う

  16. オレオレトライ⽊ • /foo/ • /baz/ • /foo/bar/ • /foo/:name[string]/ •

    /foo/bar/:id[int] ˞ύϥϝʔλͷఆٛͷ࢓ํ͸%4-ͳͷͰࣗ༝
  17. ͦΜͳ໦Ͱେৎ෉͔ʁ

  18. ⼤丈夫だ、問題ない。でも・・ ・時間的計算量(処理時間)、空間的計算量(メモ リ)をより最適化するなら、当然選択肢はある ・Radix Tree https://www.cs.usfca.edu/~galles/ visualization/RadixTree.html

  19. 3 Golangでの実装

  20. GolangでのURLパターンマッチの 仕組み、お作法

  21. net/http ・net/httpのインターフェースついて、HTTPServer を⽴てるコードの実装から内部処理を読んでおく →net/httpのmuxを拡張する ・cf. https://bmf-tech.com/posts/GolangのHTTP サーバーのコードリーディング

  22. muxとは ・マルチプレクサ。多重器、多重装置、多重化装置、合波器。 ・2つの⼊⼒から1つの出⼒を得るもの ・雑にいうとURLのパターンマッチするやつ ・net/httpではServeMux構造体(URLパターンマッチやる 君) cf. https://golang.org/pkg/net/http/#ServeMux

  23. net/httpのmuxの拡張 ・http.ListenAndServeから処理をたどる  →addressとHandlerインターフェースを満たしたhandlerを引数に 取る。内部的には、handlerの呼び出し=ServeHTTPの呼び出しとな る cf. https://golang.org/src/net/http/server.go?s=96538:96593#L3074 ・ServeMuxはServeHTTPを実装しており、Handlerインターフェー スを満たしている cf.

    https://golang.org/pkg/net/http/#ServeMux.ServeHTTP
  24. )BOEMFS*OUFSGBDF 何を拡張すればいい? IUUQ-JTUFO"OE4FSWF "EESFTT )BOEMFS 4FSWF)551 ཁ͢Δʹ͜Εʂ

  25. こんな感じ ・https://github.com/bmf-san/goblin/blob/master/ router.go#L60 ࣗલͷ63-ύλʔϯϚον

  26. ⾃前のURLパターンマッチの実装

  27. オレオレトライ⽊の実装 ・オレオレトライ⽊を実装に落とし込む →トライ⽊の応⽤。パラメータ部分の実装がちょっ と⾯倒 ・コアの実装 https://github.com/bmf-san/goblin/blob/master/trie.go

  28. 再帰処理との闘い ・つらい ・テストとデバッガで頑張れば 乗り越えられる

  29. Example ・参照実装 https://github.com/bmf-san/goblin/blob/master/_examples/main.go ・トレイリングスラッシュは気にしないで⼤丈夫なは ず ・静的ファイルはhttp.ServeFile使って問題なく返せ るはず

  30. ベンチマーク ɾࢀর https://github.com/bmf-san/goblin#benchmark →ͪΌΜͱ෼ੳͰ͖͍ͯͳ͍͚Ͳɺ΅ͪ΅ͪͳײ͢͡Δ ɾgo੡RouterͷϕϯνϚʔΫ෼ੳ https://github.com/julienschmidt/go-http-routing-benchmark

  31. Issue・PR・Star

  32. 参考 ・雑まとめ GolangͰgoblinͱ͍͏URLϧʔλʔΛࣗ࡞ͨ͠ URLϧʔςΟϯάࣗ࡞ೖ໳ɹΤϐιʔυ̍ URLϧʔςΟϯάࣗ࡞ೖ໳ɹΤϐιʔυ̎ GolangͷHTTPαʔόʔͷίʔυϦʔσΟϯά A Trie implementation in

    Golang