Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

bmf_san

May 07, 2020
Tweet

More Decks by bmf_san

Other Decks in Programming

Transcript

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

    View full-size slide

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

    View full-size slide

  3. 続編にして完結編

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  6. 1
    HTTP Routerの仕組み

    View full-size slide

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

    View full-size slide

  8. 処理のイメージ

    View full-size slide

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

    View full-size slide

  10. 2
    データ構造

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  15. オレオレトライ⽊
    • /foo/
    • /baz/
    • /foo/bar/
    • /foo/:name[string]/
    • /foo/bar/:id[int]
    ˞ύϥϝʔλͷఆٛͷ࢓ํ͸%4-ͳͷͰࣗ༝

    View full-size slide

  16. ͦΜͳ໦Ͱେৎ෉͔ʁ

    View full-size slide

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

    View full-size slide

  18. 3
    Golangでの実装

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  22. 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

    View full-size slide

  23. )BOEMFS*OUFSGBDF
    何を拡張すればいい?
    IUUQ-JTUFO"OE4FSWF
    "EESFTT )BOEMFS 4FSWF)551
    ཁ͢Δʹ͜Εʂ

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  28. Example
    ・参照実装
    https://github.com/bmf-san/goblin/blob/master/_examples/main.go
    ・トレイリングスラッシュは気にしないで⼤丈夫なは

    ・静的ファイルはhttp.ServeFile使って問題なく返せ
    るはず

    View full-size slide

  29. ベンチマーク
    ɾࢀর

    https://github.com/bmf-san/goblin#benchmark

    →ͪΌΜͱ෼ੳͰ͖͍ͯͳ͍͚Ͳɺ΅ͪ΅ͪͳײ͢͡Δ

    ɾgo੡RouterͷϕϯνϚʔΫ෼ੳ

    https://github.com/julienschmidt/go-http-routing-benchmark

    View full-size slide

  30. Issue・PR・Star

    View full-size slide

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

    View full-size slide