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
HTTPルーティングライブラリ入門 / HTTP Routing Library
Search
hikaru
August 27, 2021
1
1.2k
HTTPルーティングライブラリ入門 / HTTP Routing Library
hikaru
August 27, 2021
Tweet
Share
Featured
See All Featured
Six Lessons from altMBA
skipperchong
28
3.9k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
281
13k
Being A Developer After 40
akosma
90
590k
Rebuilding a faster, lazier Slack
samanthasiow
82
9.1k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Designing for Performance
lara
610
69k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
20
1.3k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3.1k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Transcript
HTTPルーティング ライブラリ⼊⾨ 電通国際情報サービス 宮原光
名前 宮原光 所属 電通国際情報サービス 業務 全社の案件⽀援、構成管理基盤の提供、社内ツール開発 趣味 サッカー 1 ⾃⼰紹介
2 会社概要 会社名 株式会社電通国際情報サービス(略称:ISID) 英⽂社名 Information Services International-Dentsu, Ltd. 代表者
代表取締役社⻑ 名和 亮⼀ 本社所在地 東京都港区港南2-17-1 ⽀社 関⻄⽀社/中部⽀社/豊⽥⽀社/広島⽀社 設⽴ 1975年12⽉11⽇ 資本⾦ 81億8050万円 従業員数 連結3,117名/単体1,633名(2020年12⽉末現在) ⼦会社数 17社(国内9社、海外8社) URL www.isid.co.jp 事業内容 コンサルティングからシステムの企画・設計・開発・運⽤ ・メンテナンスまで、⼀貫したソリューションを提供
3 4つの事業領域 ⾦融ソリューション ⾦融機関をはじめ企業における各種⾦融業務や、 新たな⾦融ビジネスの創出を⽀援する ITソリューションを提供しています。 製造ソリューション 製造業のエンジニアリング領域を中⼼に、 製品ライフサイクル全般を⽀援する ITソリューションを提供しています。
コミュニケーションIT 企業におけるICT基盤の構築・運⽤、 電通グループのマーケティングノウハウを活⽤した ITソリューションを提供しています。 ビジネスソリューション 会計・⼈事領域を中⼼に、企業グループの “スマートエンタープライズ” の実現を⽀援する ITソリューションを提供しています。
4 Xイノベーション本部 https://uxdc.isid.co.jp/ https://isid-exrc.jp/ https://isid-ai.jp/
• 技術ブログとしてQiitaを書いています • ぜひ、ご参照ください! • https://qiita.com/organizations/isid 技術ブログ 5
皆さんは普段、 Webアプリケーションを開発する際、 どんなライブラリを使いますか? 6
DefaultServeMux 7 https://pkg.go.dev/net/
[email protected]
gorilla/mux 8 https://github.com/gorilla/mux
go-chi/chi 9 https://github.com/go-chi/chi
• 共通してハンドラの登録、呼び出しの役割を担う • 本セッションではHTTPルーティングライブラリと定義します HTTPルーティングライブラリ 10
11 HTTPルーティングライブラリの中⾝は どうなっているのだろう
12 実際に作りながら学んでみた
• パスベースルーティングに対応 • パスパラメータ取得に対応 TinyRouter 13 学習⽬的なので極⼒シンプルな仕様に
• ハンドラの登録メソッド • パスとハンドラを受け取る • 各HTTPメソッドごとの登録メソッド インターフェース 14
• http.Handlerを満たす • http.ListenAndServeやhttp.Server でも利⽤可能 • 実際のハンドラの出しわけの ロジックを記述 インターフェース 15
完成形 16
17 パスベースルーティング
ルーティングライブラリの流れ 18 ルーティング ライブラリ ハンドラ1 GET /users 登録メソッド
ルーティングライブラリの流れ 20 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ2 POST /users
登録メソッド
ルーティングライブラリの流れ 20 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books
ハンドラ2 POST /users 登録メソッド
ルーティングライブラリの流れ 21 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books
GET https://example.com/books Request ハンドラ2 POST /users ServeHTTPメソッド
ルーティングライブラリの流れ 22 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books
ハンドラ2 POST /users GET https://exam ple.com /books ServeHTTPメソッド
• ハンドラを登録する • ハンドラのHTTPメソッドとパスをリクエストと順に⽐較する • HTTPメソッドとパスの⽂字列が⼀致したらハンドラを呼び出す パスベースルーティングの実装1 23
パスベースルーティングの実装1 24 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books
GET https://example.com/books Request ハンドラ2 POST /users ServeHTTPメソッド
パスベースルーティングの実装1 25 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books
GET /books Request ハンドラ2 POST /users ServeHTTPメソッド
パスベースルーティングの実装1 26 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books
GET /books Request ハンドラ2 POST /users ServeHTTPメソッド
パスベースルーティングの実装1 27 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books
ハンドラ2 POST /users GET /books Request ServeHTTPメソッド
パスベースルーティングの実装1 28 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /users/{id}
GET https://example.com/users/1 Request ハンドラ2 POST /users ServeHTTPメソッド
パスベースルーティングの実装1 29 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /users/{id}
ハンドラ2 POST /users GET /users/1 Request ServeHTTPメソッド
• ハンドラのHTTPメソッドとパスをリクエストと順に⽐較する⽅針は良さそう • ⽂字列の完全⼀致だとパスパラメータに対応できない パスベースルーティングの実装1 30 そこで正規表現を利⽤する
• ハンドラ登録時にパスを正規表現に変換する • ハンドラのHTTPメソッドとパスをリクエストと順に⽐較する • HTTPメソッドが⼀致する、かつ、パスの正規表現がマッチしたらハンドラを呼び出す パスベースルーティングの実装2 31
• /users/{id} を^/users/([^/]+)[/]?$へと変換 • /users/abcや/users/123/の⽂字列にマッチする • [^/]+は/以外の⽂字列の1回以上の繰り返し • [/]?で末尾に/がある場合とない場合に対応 正規表現への変換
32
パスベースルーティングの実装2 33 ルーティング ライブラリ ハンドラ1 GET ^/users[/]?$ ハンドラ3 GET ^/users/([^/]+)[/]?$
GET https://example.com/users/1 Request ハンドラ2 POST ^/users[/]?$ ServeHTTPメソッド
パスベースルーティングの実装2 34 ルーティング ライブラリ ハンドラ1 GET ^/users[/]?$ ハンドラ3 GET ^/users/([^/]+)[/]?$
ハンドラ2 POST ^/users[/]?$ GET /users/1 Request ServeHTTPメソッド
35 パスパラメータの取得
パスパラメータの取得 36 • パスの正規表現と regexp.Regexpの FindStringSubmatchを利⽤する • FindStringSubmatchは()に マッチした値を返してくれる
パスパラメータの取得 37 • ハンドラ登録時にパラメータ名を取得 • FindStringSubmatchで値を取得 • パラメータ名と値の組みをmap[string]interface{}に⼊れる • mapをhttp.Request内のcontextに⼊れる
• contextから値を取り出す関数を提供
38 実装
• インターフェースを満たす • routeのスライスをフィールドに持つ • routeは1ハンドラに対応する • 登録メソッドでrouteを作成し、スライスに追加 TinyRouter構造体 39
ServeHTTPメソッド 40 • リクエストとハンドラを⽐較 • マッチしたらハンドラを取り出す • for⽂を抜ける
ServeHTTPメソッド 41 • パラメーターをセット • ハンドラを呼び出す
42 これでルーティングライブラリの完成
43 ベンチマークしてみる
ベンチマーク 44 • testingパッケージのベンチマーク機能を利⽤ • tinyrouter, gorilla/mux, go-chi/chiを⽐較 • GitHubの756のエンドポイントを登録し、リクエストを投げる
ベンチマーク結果 45 • chiの試⾏回数が他に⽐べて⼀桁多い • メモリ使⽤量、アロケーション数に⼤きな差はない
基数⽊ 46 Claudio Rocchini - 投稿者⾃⾝による作品, CC 表⽰ 2.5, https://commons.wikimedia.org/w/index.php?curid=2118795による
• chiはルーティングアルゴリズムに基数⽊を使⽤ • 各パスからツリーを構築
まとめ 47 • 全探索と正規表現を使ってルーティングライブラリを作ってみた • ルーティングは⽂字列アルゴリズムと深く関係していた • 今回のリポジトリは以下で公開しております! • https://github.com/hikaru7719/tinyrouter