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
Designing for Performance
lara
609
69k
Docker and Python
trallard
44
3.4k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
2.8k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
60k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Product Roadmaps are Hard
iamctodd
PRO
53
11k
Automating Front-end Workflow
addyosmani
1370
200k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
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