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
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
9.5k
How to make the Groovebox
asonas
2
1.9k
Believing is Seeing
oripsolob
1
53
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
From π to Pie charts
rasagy
0
120
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.2k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.6k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.1k
Darren the Foodie - Storyboard
khoart
PRO
2
2.4k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Done Done
chrislema
186
16k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
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