Slide 1

Slide 1 text

HTTPルーティング ライブラリ⼊⾨ 電通国際情報サービス 宮原光

Slide 2

Slide 2 text

名前 宮原光 所属 電通国際情報サービス 業務 全社の案件⽀援、構成管理基盤の提供、社内ツール開発 趣味 サッカー 1 ⾃⼰紹介

Slide 3

Slide 3 text

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 事業内容 コンサルティングからシステムの企画・設計・開発・運⽤ ・メンテナンスまで、⼀貫したソリューションを提供

Slide 4

Slide 4 text

3 4つの事業領域 ⾦融ソリューション ⾦融機関をはじめ企業における各種⾦融業務や、 新たな⾦融ビジネスの創出を⽀援する ITソリューションを提供しています。 製造ソリューション 製造業のエンジニアリング領域を中⼼に、 製品ライフサイクル全般を⽀援する ITソリューションを提供しています。 コミュニケーションIT 企業におけるICT基盤の構築・運⽤、 電通グループのマーケティングノウハウを活⽤した ITソリューションを提供しています。 ビジネスソリューション 会計・⼈事領域を中⼼に、企業グループの “スマートエンタープライズ” の実現を⽀援する ITソリューションを提供しています。

Slide 5

Slide 5 text

4 Xイノベーション本部 https://uxdc.isid.co.jp/ https://isid-exrc.jp/ https://isid-ai.jp/

Slide 6

Slide 6 text

• 技術ブログとしてQiitaを書いています • ぜひ、ご参照ください! • https://qiita.com/organizations/isid 技術ブログ 5

Slide 7

Slide 7 text

皆さんは普段、 Webアプリケーションを開発する際、 どんなライブラリを使いますか? 6

Slide 8

Slide 8 text

DefaultServeMux 7 https://pkg.go.dev/net/[email protected]

Slide 9

Slide 9 text

gorilla/mux 8 https://github.com/gorilla/mux

Slide 10

Slide 10 text

go-chi/chi 9 https://github.com/go-chi/chi

Slide 11

Slide 11 text

• 共通してハンドラの登録、呼び出しの役割を担う • 本セッションではHTTPルーティングライブラリと定義します HTTPルーティングライブラリ 10

Slide 12

Slide 12 text

11 HTTPルーティングライブラリの中⾝は どうなっているのだろう

Slide 13

Slide 13 text

12 実際に作りながら学んでみた

Slide 14

Slide 14 text

• パスベースルーティングに対応 • パスパラメータ取得に対応 TinyRouter 13 学習⽬的なので極⼒シンプルな仕様に

Slide 15

Slide 15 text

• ハンドラの登録メソッド • パスとハンドラを受け取る • 各HTTPメソッドごとの登録メソッド インターフェース 14

Slide 16

Slide 16 text

• http.Handlerを満たす • http.ListenAndServeやhttp.Server でも利⽤可能 • 実際のハンドラの出しわけの ロジックを記述 インターフェース 15

Slide 17

Slide 17 text

完成形 16

Slide 18

Slide 18 text

17 パスベースルーティング

Slide 19

Slide 19 text

ルーティングライブラリの流れ 18 ルーティング ライブラリ ハンドラ1 GET /users 登録メソッド

Slide 20

Slide 20 text

ルーティングライブラリの流れ 20 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ2 POST /users 登録メソッド

Slide 21

Slide 21 text

ルーティングライブラリの流れ 20 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books ハンドラ2 POST /users 登録メソッド

Slide 22

Slide 22 text

ルーティングライブラリの流れ 21 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books GET https://example.com/books Request ハンドラ2 POST /users ServeHTTPメソッド

Slide 23

Slide 23 text

ルーティングライブラリの流れ 22 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books ハンドラ2 POST /users GET https://exam ple.com /books ServeHTTPメソッド

Slide 24

Slide 24 text

• ハンドラを登録する • ハンドラのHTTPメソッドとパスをリクエストと順に⽐較する • HTTPメソッドとパスの⽂字列が⼀致したらハンドラを呼び出す パスベースルーティングの実装1 23

Slide 25

Slide 25 text

パスベースルーティングの実装1 24 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books GET https://example.com/books Request ハンドラ2 POST /users ServeHTTPメソッド

Slide 26

Slide 26 text

パスベースルーティングの実装1 25 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books GET /books Request ハンドラ2 POST /users ServeHTTPメソッド

Slide 27

Slide 27 text

パスベースルーティングの実装1 26 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books GET /books Request ハンドラ2 POST /users ServeHTTPメソッド

Slide 28

Slide 28 text

パスベースルーティングの実装1 27 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /books ハンドラ2 POST /users GET /books Request ServeHTTPメソッド

Slide 29

Slide 29 text

パスベースルーティングの実装1 28 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /users/{id} GET https://example.com/users/1 Request ハンドラ2 POST /users ServeHTTPメソッド

Slide 30

Slide 30 text

パスベースルーティングの実装1 29 ルーティング ライブラリ ハンドラ1 GET /users ハンドラ3 GET /users/{id} ハンドラ2 POST /users GET /users/1 Request ServeHTTPメソッド

Slide 31

Slide 31 text

• ハンドラのHTTPメソッドとパスをリクエストと順に⽐較する⽅針は良さそう • ⽂字列の完全⼀致だとパスパラメータに対応できない パスベースルーティングの実装1 30 そこで正規表現を利⽤する

Slide 32

Slide 32 text

• ハンドラ登録時にパスを正規表現に変換する • ハンドラのHTTPメソッドとパスをリクエストと順に⽐較する • HTTPメソッドが⼀致する、かつ、パスの正規表現がマッチしたらハンドラを呼び出す パスベースルーティングの実装2 31

Slide 33

Slide 33 text

• /users/{id} を^/users/([^/]+)[/]?$へと変換 • /users/abcや/users/123/の⽂字列にマッチする • [^/]+は/以外の⽂字列の1回以上の繰り返し • [/]?で末尾に/がある場合とない場合に対応 正規表現への変換 32

Slide 34

Slide 34 text

パスベースルーティングの実装2 33 ルーティング ライブラリ ハンドラ1 GET ^/users[/]?$ ハンドラ3 GET ^/users/([^/]+)[/]?$ GET https://example.com/users/1 Request ハンドラ2 POST ^/users[/]?$ ServeHTTPメソッド

Slide 35

Slide 35 text

パスベースルーティングの実装2 34 ルーティング ライブラリ ハンドラ1 GET ^/users[/]?$ ハンドラ3 GET ^/users/([^/]+)[/]?$ ハンドラ2 POST ^/users[/]?$ GET /users/1 Request ServeHTTPメソッド

Slide 36

Slide 36 text

35 パスパラメータの取得

Slide 37

Slide 37 text

パスパラメータの取得 36 • パスの正規表現と regexp.Regexpの FindStringSubmatchを利⽤する • FindStringSubmatchは()に マッチした値を返してくれる

Slide 38

Slide 38 text

パスパラメータの取得 37 • ハンドラ登録時にパラメータ名を取得 • FindStringSubmatchで値を取得 • パラメータ名と値の組みをmap[string]interface{}に⼊れる • mapをhttp.Request内のcontextに⼊れる • contextから値を取り出す関数を提供

Slide 39

Slide 39 text

38 実装

Slide 40

Slide 40 text

• インターフェースを満たす • routeのスライスをフィールドに持つ • routeは1ハンドラに対応する • 登録メソッドでrouteを作成し、スライスに追加 TinyRouter構造体 39

Slide 41

Slide 41 text

ServeHTTPメソッド 40 • リクエストとハンドラを⽐較 • マッチしたらハンドラを取り出す • for⽂を抜ける

Slide 42

Slide 42 text

ServeHTTPメソッド 41 • パラメーターをセット • ハンドラを呼び出す

Slide 43

Slide 43 text

42 これでルーティングライブラリの完成

Slide 44

Slide 44 text

43 ベンチマークしてみる

Slide 45

Slide 45 text

ベンチマーク 44 • testingパッケージのベンチマーク機能を利⽤ • tinyrouter, gorilla/mux, go-chi/chiを⽐較 • GitHubの756のエンドポイントを登録し、リクエストを投げる

Slide 46

Slide 46 text

ベンチマーク結果 45 • chiの試⾏回数が他に⽐べて⼀桁多い • メモリ使⽤量、アロケーション数に⼤きな差はない

Slide 47

Slide 47 text

基数⽊ 46 Claudio Rocchini - 投稿者⾃⾝による作品, CC 表⽰ 2.5, https://commons.wikimedia.org/w/index.php?curid=2118795による • chiはルーティングアルゴリズムに基数⽊を使⽤ • 各パスからツリーを構築

Slide 48

Slide 48 text

まとめ 47 • 全探索と正規表現を使ってルーティングライブラリを作ってみた • ルーティングは⽂字列アルゴリズムと深く関係していた • 今回のリポジトリは以下で公開しております! • https://github.com/hikaru7719/tinyrouter