Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
GolangでURLルーターをつくった
Search
bmf_san
May 07, 2020
Programming
370
1
Share
GolangでURLルーターをつくった
bmf_san
May 07, 2020
More Decks by bmf_san
See All by bmf_san
桃太郎で始めるRego入門‐今日から使えるRegoの基本編
bmf_san
0
49
完璧を求めない意思決定-アクセス制御基盤における制約との向き合い方
bmf_san
5
18k
AAPについて調べてみた
bmf_san
0
100
レーダーをつくる
bmf_san
0
69
契約テストとPactについて
bmf_san
0
110
5分でわかるSLO
bmf_san
2
160
権限について考える
bmf_san
2
150
自作HTTPルーターから新しいServeMuxへ
bmf_san
3
1.8k
古くなってしまったPHPフレームワークとPHPのバージョンアップ戦略
bmf_san
1
490
Other Decks in Programming
See All in Programming
mruby on C#: From VM Implementation to Game Scripting (RubyKaigi 2026)
hadashia
1
200
Alternatives to JPA 2026
debop
0
110
ファインチューニングせずメインコンペを解く方法
pokutuna
0
310
瑠璃の宝石に学ぶ技術の声の聴き方 / 【劇場版】アニメから得た学びを発表会2026 #エンジニアニメ
mazrean
0
240
レガシーPHP転生 〜父がドメインエキスパートだったのでDDD+Claude Codeでチート開発します〜
panda_program
0
880
CursorとClaudeCodeとCodexとOpenCodeを実際に比較してみた
terisuke
1
440
AI時代の脳疲弊と向き合う ~言語学としてのPHP~
sakuraikotone
1
1.9k
Mastering Event Sourcing: Your Parents Holidayed in Yugoslavia
super_marek
0
150
感情を設計する
ichimichi
5
1.4k
存在論的プログラミング: 時間と存在を記述する
koriym
5
870
アクセシビリティ試験の"その後"を仕組み化する
yuuumiravy
0
130
Claude Codeをカスタムして自分だけのClaude Codeを作ろう
terisuke
0
120
Featured
See All Featured
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1k
The Limits of Empathy - UXLibs8
cassininazir
1
290
Un-Boring Meetings
codingconduct
0
260
Scaling GitHub
holman
464
140k
Writing Fast Ruby
sferik
630
63k
Automating Front-end Workflow
addyosmani
1370
200k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.6k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
330
A better future with KSS
kneath
240
18k
The untapped power of vector embeddings
frankvandijk
2
1.7k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
170
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Transcript
GolangでHTTP Routerをつくった @bmf_san
https://speakerdeck.com/bmf_san/urlruteinguwotukuruepisodo1
続編にして完結編
⽬次 ・HTTP Routerの仕組み ・データ構造 ・Golangでの実装
Github https://github.com/bmf-san/goblin
1 HTTP Routerの仕組み
HTTP Router is 何? ・リクエストされたURLやHTTP Methodに応じて、 処理の実⾏を制御するアプリケーション ・URLとアプリケーションの処理を結びつける
処理のイメージ
パターン Routerが解釈するルーティングのパターン ・静的なルーティング →/foo/barが/foo/barに⼀致 ・動的なルーティング →/foo/bar/123が/foo/bar/:idに⼀致
2 データ構造
データ構造を考える ・Router≒⽂字列マッチング ・URLの階層構造と相性が良いデータ構造 →⽊構造
⽊構造
トライ⽊(プレフィックス⽊) ・⽂字列の集合を扱う⽊構造の⼀種 ・ざっくりいうと、⽂字列を探索しやすいように⽊に 格納したやつ ・ex. サジェスト、IPアドレス探索、形態素解析とか に応⽤が⾒られる
トライ⽊を知る ・https://www.cs.usfca.edu/~galles/visualization/ Trie.html →アルゴリズムのビジュアライズ ・https://github.com/bmf-san/road-to-algorithm- master/tree/master/data_structures/tree/trie →参照実装かいた
オレオレトライ⽊ ・ルーティングの定義を元にオレオレトライ⽊をつく る(これが結構試⾏錯誤した..) ・トライ⽊の定義に当てはまるのかちょっと⾃信ない けど多分トライ⽊、いやギリトライ⽊だと思う
オレオレトライ⽊ • /foo/ • /baz/ • /foo/bar/ • /foo/:name[string]/ •
/foo/bar/:id[int] ˞ύϥϝʔλͷఆٛͷํ%4-ͳͷͰࣗ༝
ͦΜͳͰେৎ͔ʁ
⼤丈夫だ、問題ない。でも・・ ・時間的計算量(処理時間)、空間的計算量(メモ リ)をより最適化するなら、当然選択肢はある ・Radix Tree https://www.cs.usfca.edu/~galles/ visualization/RadixTree.html
3 Golangでの実装
GolangでのURLパターンマッチの 仕組み、お作法
net/http ・net/httpのインターフェースついて、HTTPServer を⽴てるコードの実装から内部処理を読んでおく →net/httpのmuxを拡張する ・cf. https://bmf-tech.com/posts/GolangのHTTP サーバーのコードリーディング
muxとは ・マルチプレクサ。多重器、多重装置、多重化装置、合波器。 ・2つの⼊⼒から1つの出⼒を得るもの ・雑にいうとURLのパターンマッチするやつ ・net/httpではServeMux構造体(URLパターンマッチやる 君) cf. https://golang.org/pkg/net/http/#ServeMux
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
)BOEMFS*OUFSGBDF 何を拡張すればいい? IUUQ-JTUFO"OE4FSWF "EESFTT )BOEMFS 4FSWF)551 ཁ͢Δʹ͜Εʂ
こんな感じ ・https://github.com/bmf-san/goblin/blob/master/ router.go#L60 ࣗલͷ63-ύλʔϯϚον
⾃前のURLパターンマッチの実装
オレオレトライ⽊の実装 ・オレオレトライ⽊を実装に落とし込む →トライ⽊の応⽤。パラメータ部分の実装がちょっ と⾯倒 ・コアの実装 https://github.com/bmf-san/goblin/blob/master/trie.go
再帰処理との闘い ・つらい ・テストとデバッガで頑張れば 乗り越えられる
Example ・参照実装 https://github.com/bmf-san/goblin/blob/master/_examples/main.go ・トレイリングスラッシュは気にしないで⼤丈夫なは ず ・静的ファイルはhttp.ServeFile使って問題なく返せ るはず
ベンチマーク ɾࢀর https://github.com/bmf-san/goblin#benchmark →ͪΌΜͱੳͰ͖͍ͯͳ͍͚Ͳɺ΅ͪ΅ͪͳײ͢͡Δ ɾgoRouterͷϕϯνϚʔΫੳ https://github.com/julienschmidt/go-http-routing-benchmark
Issue・PR・Star
参考 ・雑まとめ GolangͰgoblinͱ͍͏URLϧʔλʔΛࣗ࡞ͨ͠ URLϧʔςΟϯάࣗ࡞ೖɹΤϐιʔυ̍ URLϧʔςΟϯάࣗ࡞ೖɹΤϐιʔυ̎ GolangͷHTTPαʔόʔͷίʔυϦʔσΟϯά A Trie implementation in
Golang