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
Embracing the Ebb and Flow
colly
85
4.6k
Faster Mobile Websites
deanohume
306
31k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7.1k
How STYLIGHT went responsive
nonsquared
99
5.5k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
118
51k
The Language of Interfaces
destraynor
157
24k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Gamification - CAS2011
davidbonilla
81
5.2k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.5k
Why Our Code Smells
bkeepers
PRO
336
57k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
102
19k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.4k
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/http@go1.16.6
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