Submit Search
WebAPIのバリデーションを、型の力でいい感じにする
0 likes
176 views
Takuya Kikuchi
Web API LT会 - vol.3 #webapilt
Technology
Read more
1 of 20
Download now
Download to read offline
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
More Related Content
PDF
Elixir Meetup #1 Loggerの構造と拡張
Sugawara Genki
PDF
Ruby風Swift NSOperation編
Hisakuni Fujimoto
PDF
20150908 ”時間の流れ” という無限リストを扱うAWS Lambda
都元ダイスケ Miyamoto
PDF
AWSをコードで定義する
Sugawara Genki
PDF
API Gatewayで re:Inventのセッション探し
Ryo Nakamaru
PDF
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
Narami Kiyokura
PDF
Visual studio 14 CTP2 概要
Yoshihisa Ozaki
PDF
React Native GUIDE
dcubeio
Elixir Meetup #1 Loggerの構造と拡張
Sugawara Genki
Ruby風Swift NSOperation編
Hisakuni Fujimoto
20150908 ”時間の流れ” という無限リストを扱うAWS Lambda
都元ダイスケ Miyamoto
AWSをコードで定義する
Sugawara Genki
API Gatewayで re:Inventのセッション探し
Ryo Nakamaru
ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた
Narami Kiyokura
Visual studio 14 CTP2 概要
Yoshihisa Ozaki
React Native GUIDE
dcubeio
What's hot
(20)
PDF
20140930 anything as_code
Sugawara Genki
PPT
CGI::Application::Dispatch
Hideo Kimura
PDF
認証機能で学ぶ Laravel 5 アプリケーション
Masashi Shinbara
PDF
PHPという概念が存在しない退屈な世界 - AWS LambdaでWebAPP編
Yoshihiro Ohsuka
PDF
Phpでrest apiを作った話
Yamaguchi Kenya
PDF
私のチームのリーダブルコード
Keisuke Tameyasu
PDF
PHPコードではなく PHPコードの「書き方」を知る
Masashi Shinbara
PDF
勉強会20140207
Shugo Numano
PDF
serverless framework + AWS Lambda with Python
masahitojp
PDF
もう XAMPP / MAMP はいらない! Vagrant で作る PHP 開発環境
Masashi Shinbara
KEY
CMS for Cloud by Ruby
Masaki Komagata
PDF
Ansible 2.0 のサマライズとこれから
Takeshi Kuramochi
PDF
Heroku+MongoLabでダミーサーバー
Hironytic
PDF
Scala + Finagleの魅力
Kota Mizushima
PDF
React.jsでサービスを作ってみた話
GIG inc.
PDF
Vagrant で PHP 開発環境を作る ハンズオン
Masashi Shinbara
PDF
Ansible ではじめるサーバ作業の自動化
Masashi Shinbara
PPT
Scala on Hadoop
Shinji Tanaka
PDF
Twilio API を PHP で触ってみよう
Masashi Shinbara
PDF
OSSから学ぶSwift実践テクニック
庸介 高橋
20140930 anything as_code
Sugawara Genki
CGI::Application::Dispatch
Hideo Kimura
認証機能で学ぶ Laravel 5 アプリケーション
Masashi Shinbara
PHPという概念が存在しない退屈な世界 - AWS LambdaでWebAPP編
Yoshihiro Ohsuka
Phpでrest apiを作った話
Yamaguchi Kenya
私のチームのリーダブルコード
Keisuke Tameyasu
PHPコードではなく PHPコードの「書き方」を知る
Masashi Shinbara
勉強会20140207
Shugo Numano
serverless framework + AWS Lambda with Python
masahitojp
もう XAMPP / MAMP はいらない! Vagrant で作る PHP 開発環境
Masashi Shinbara
CMS for Cloud by Ruby
Masaki Komagata
Ansible 2.0 のサマライズとこれから
Takeshi Kuramochi
Heroku+MongoLabでダミーサーバー
Hironytic
Scala + Finagleの魅力
Kota Mizushima
React.jsでサービスを作ってみた話
GIG inc.
Vagrant で PHP 開発環境を作る ハンズオン
Masashi Shinbara
Ansible ではじめるサーバ作業の自動化
Masashi Shinbara
Scala on Hadoop
Shinji Tanaka
Twilio API を PHP で触ってみよう
Masashi Shinbara
OSSから学ぶSwift実践テクニック
庸介 高橋
Ad
Similar to WebAPIのバリデーションを、型の力でいい感じにする
(20)
PPT
Inside mobage platform
Toru Yamaguchi
PPTX
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
ssuser8b389c
PDF
SendGrid SDKを捨てた話
Yuta Matsumura
PDF
社内勉強会資料(Varnish Module)
Iwana Chan
PDF
VSCodeで始めるAzure Static Web Apps開発
Yuta Matsumura
PDF
OpenStack API
Akira Yoshiyama
PDF
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Shotaro Suzuki
PPTX
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
fukuoka.ex
PDF
Node.jsとAWS入門(Elastic Beanstalk & AWS SDK for Node.js)
崇之 清水
PDF
How to Make Own Framework built on OWIN
Yoshifumi Kawai
PDF
ソーシャルアプリ勉強会(第一回資料)配布用
Yatabe Terumasa
PDF
WTM53 phpフレームワーク いまさらcodeigniter
Masanori Oobayashi
PDF
Chef+serverspec+werckerでインフラCIする話
Masayuki Morita
PDF
Container Storage Interface のすべて
祐司 伊藤
PDF
Hakodate - simple framework
Hiroaki Murayama
PDF
初めての Data api cms どうでしょう - 大阪夏の陣
Yuji Takayama
PDF
Server side Swift & Photo Booth
LINE Corporation
PPT
Ruby on Rails Tutorial Chapter5-7
Sea Mountain
PPTX
ネットワーク機器のAPIあれこれ入門(NetOpsCoding#2)
Kentaro Ebisawa
PDF
最近のRails開発のはなし
Yoichi Toyota
Inside mobage platform
Toru Yamaguchi
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
ssuser8b389c
SendGrid SDKを捨てた話
Yuta Matsumura
社内勉強会資料(Varnish Module)
Iwana Chan
VSCodeで始めるAzure Static Web Apps開発
Yuta Matsumura
OpenStack API
Akira Yoshiyama
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Shotaro Suzuki
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
fukuoka.ex
Node.jsとAWS入門(Elastic Beanstalk & AWS SDK for Node.js)
崇之 清水
How to Make Own Framework built on OWIN
Yoshifumi Kawai
ソーシャルアプリ勉強会(第一回資料)配布用
Yatabe Terumasa
WTM53 phpフレームワーク いまさらcodeigniter
Masanori Oobayashi
Chef+serverspec+werckerでインフラCIする話
Masayuki Morita
Container Storage Interface のすべて
祐司 伊藤
Hakodate - simple framework
Hiroaki Murayama
初めての Data api cms どうでしょう - 大阪夏の陣
Yuji Takayama
Server side Swift & Photo Booth
LINE Corporation
Ruby on Rails Tutorial Chapter5-7
Sea Mountain
ネットワーク機器のAPIあれこれ入門(NetOpsCoding#2)
Kentaro Ebisawa
最近のRails開発のはなし
Yoichi Toyota
Ad
WebAPIのバリデーションを、型の力でいい感じにする
1.
confidential WebAPIのバリデーションを、型の力でいい感じにする Web API LT会
- vol.3 takuya kikuchi / Showcase Gig
2.
confidential ©Showcase Gig 自己紹介 ● takuya
kikuchi ● twitter: @_pochi ● Engineer Group Manager @ Showcase Gig ● モバイルオーダープラットフォームを作っています ● たまに実店舗も作ります
3.
confidential ©Showcase Gig APIが受け取るパラメータのバリデーション ちゃんとできてますか? SDK, OpenAPI,
gRPC, etc… 「そんな入力予期してなかった・・・」 「そんな使い方しないで・・・」
4.
confidential ©Showcase Gig 素直なアプローチ紹介 gRPCの例 protoc-gen-validate を使ってバリデータの自動生成ができるよ
🐔 参考: 【Go】gRPCのリクエストバリデータを自動生成する https://note.com/scg_tech/n/nb12a33bfd391 import "github.com/envoyproxy/protoc-gen-validate/validate/validate.proto"; ~~~~~~~~~~~ service TestServer { rpc Test(TestMessage) returns (Result) {} } ~~~~~~~~~~~ message TestMessage { // 0~100間の整数 int32 seisuu = 1 [(validate.rules).int32 = {gte:0, lt: 100}]; // floatで0~1の値 double fudou = 2 [(validate.rules).double = {gte: 0, lte: 1}]; // アルファベットと数値で、5〜30文字のrepeated repeated string mojiretsu = 3 [(validate.rules).repeated.items.string = {pattern: "^[a-z0-9]{5,30}$", min_len: 5, max_len:30}]; // RFC 1034で解釈可能なメールアドレス string mail_address = 4 [(validate.rules).string.email = true]; }
5.
confidential ©Showcase Gig 型の話をします
6.
confidential ©Showcase Gig 型はいいぞ ● 静的型付け言語では、コンパイル時に型チェックをしてくれる ●
型の明らかな渡し間違いはすぐ気づくことができる import "fmt" func main() { var intValue int = 12345 printString (intValue) } func printString (str string) { fmt.Printf("%sn", str) } import "fmt" func main() { var str string = "文字列だよ" printString (str) } func printString (str string) { fmt.Printf("%sn", str) } コンパイルOK コンパイルエラー
7.
confidential ©Showcase Gig しかし基本データ型には限界がある ● メールアドレスのみを受け入れたいのだけど、コンパイラさん気づいてくれない import
"fmt" func main() { var mailAddress string = "メアドではないよ" printMailAddress (mailAddress) } func printMailAddress (mailAddress string) { fmt.Printf("%sn", mailAddress) } import "fmt" func main() { var mailAddress string = "hoge@example.com" printMailAddress (mailAddress) } func printMailAddress (mailAddress string) { fmt.Printf("%sn", mailAddress) } コンパイルOK 🤗 コンパイルOK 😢
8.
confidential ©Showcase Gig しかし基本データ型には限界がある ● そもそもユーザーから任意の値が入力されるものはどうしようもない import
"fmt" func main() { var str string // ユーザー入力を受け取る _, err := fmt.Scan(&str) if err != nil { // 読み取り失敗 return } printMailAddress(str) } コンパイルOK。ただしメアド以外も printできてしまう。
9.
confidential ©Showcase Gig さてどうする
10.
confidential ©Showcase Gig 「メールアドレス」型を作ろう ● 正しいメアド入力以外はオブジェクトを生成できないようにする type
MailAddress string func NewMailAddress (mailAddress string) (MailAddress , error) { if !isValidMailAddress (mailAddress) { return "", errors.New("メアドではないので NG") } return MailAddress (mailAddress) , nil } func printMailAddress(mailAddress MailAddress) { fmt.Printf("%sn", mailAddress) } 型とコンストラクタを定義。コンストラクタで、「正しいメールアド レスかどうか」をチェックする printMailAddressメソッドの引数も、その型を受け取るようにする
11.
confidential ©Showcase Gig 「メールアドレス」型を活用する ● コンパイル時チェックはできないが、「メールアドレスじゃない文字列が渡された場合」のエラーハンドリング実装が強制さ れる ○
なので、「うっかりメアドじゃない文字列が渡されてクラッシュ!」みたいなことが回避できる func main() { var str string // ユーザー入力を受け取る _, err := fmt.Scan(&str) if err != nil { // 読み取り失敗 return } // 入力された文字列から、 MailAddressオブジェクト生成 mailAddress, err := NewMailAddress (str) if err != nil { // メールアドレスではない文字列が渡された return } // MailAddress を出力する printMailAddress (mailAddress) }
12.
confidential ©Showcase Gig 本題。WebAPIの話
13.
confidential ©Showcase Gig メールアドレスを登録するWebAPI ● メールアドレスを受け取ってDBに記録するエンドポイントのコントローラをイメージしてください ●
MailAddressRepositoryは単にSQLを呼ぶだけの実装だと思ってください // メールアドレスを登録するエンドポイントの実装 func updateMailAddressController (userID int, mailAddress string) error { // DBアクセス用のリポジトリ取得 repository := newMailAddressRepository () // DBに書き込み err := repository. Update(userID, mailAddress) if err != nil { // DB書き込みエラー return errors.New("internal error" ) } // 正常終了 return nil } type MailAddressRepository interface { Update(userID int, mailAddress string) error }
14.
confidential ©Showcase Gig 問題点 ● mailAddress
のバリデーションをしていない。 ○ 渡されてくるmailAddress次第でいろんなエラーが起きてしまう ■ メアドじゃなくても登録できる(それはダメ!) ■ 文字列が長すぎたらDBへのクエリでエラーが起きて internal error (カッコ悪い!) ● メアドじゃない文字列が渡されたらクライアントエラーにしてあげたい // メールアドレスを登録するエンドポイントの実装 func updateMailAddressController (userID int, mailAddress string) error { // DBアクセス用のリポジトリ取得 repository := newMailAddressRepository () // DBに書き込み err := repository. Update(userID, mailAddress) if err != nil { // DB書き込みエラー return errors.New("internal error" ) } // 正常終了 return nil }
15.
confidential ©Showcase Gig 先程作ったメールアドレス型を使います ● MailAddressRepositoryの引数を、string
から MailAddress型に変更 type MailAddressRepository interface { Update(userID int, mailAddress MailAddress) error } type MailAddressRepository interface { Update(userID int, mailAddress string) error }
16.
confidential ©Showcase Gig するとどうなるか ● 元のコードに戻ります。 ●
mailAddressが string なのでコンパイルエラーになります // メールアドレスを登録するエンドポイントの実装 func updateMailAddressController (userID int, mailAddress string) error { // DBアクセス用のリポジトリ repository := newMailAddressRepository () // DBに書き込み err := repository. Update(userID, mailAddress) if err != nil { // DB書き込みエラー return errors.New("internal error" ) } // 正常終了 return nil }
17.
confidential ©Showcase Gig あとはコンパイルエラーを解消する ● コンパイルエラーを解消するために、引数で渡された文字列をMailAddress型に変換します ●
その際にエラーハンドリングがごく自然に実装されます // メールアドレスを登録するエンドポイントの実装 func updateMailAddressController (userID int, mailAddressStr string) error { // DBアクセス用のリポジトリ repository := newMailAddressRepository () mailAddress, err := NewMailAddress(mailAddressStr) if err != nil { // 渡された文字列がメールアドレスではない return errors.New("client error") } // DBに書き込み err = repository. Update(userID, mailAddress) if err != nil { // DB書き込みエラー return errors.New("internal error" ) } // 正常終了 return nil }
18.
confidential ©Showcase Gig まとめ リクエストパラメータをバリデーションしたいあなたへ → バリデーションしたいということは、その値には何らかのルールがある →
そのルールを表現する、専用の型を用意してみよう → 専用の型の利用を強制しよう → すると、パラメータのバリデーションは自然に実装される
19.
confidential ©Showcase Gig おしまい
20.
confidential ©Showcase Gig 宣伝 ● APIが好きな人 ●
型が好きな人 ● Goが好きな人 ● gRPCが好きな人 ● エンジニアリングが好きな人 ● POSが好きな人 ● 次世代店舗を作りたい人 https://www.showcase-gig.com/recruit/engineer/
Download