focuslight-validator validate sinatra application - validation night at LINE corporation
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

focuslight-validator validate sinatra application - validation night at LINE corporation

  • 139 views
Uploaded on

validation night

validation night

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
139
On Slideshare
97
From Embeds
42
Number of Embeds
1

Actions

Shares
Downloads
0
Comments
0
Likes
1

Embeds 42

https://twitter.com 42

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. focuslight-validator validate sinatra application Satoshi SUZUKI, @studio3104 validation night at LINE Corp. Dec 4, 2014 1
  • 2. who? Satoshi SUZUKI » Twitter: @studio3104 » GitHub: studio3104 » Work: LINE Corporation validation night at LINE Corp. Dec 4, 2014 2
  • 3. suddenly, validation night at LINE Corp. Dec 4, 2014 3
  • 4. Do you know GrowthForecast ? validation night at LINE Corp. Dec 4, 2014 4
  • 5. Ok. Well, validation night at LINE Corp. Dec 4, 2014 5
  • 6. Do you know Focuslight ? validation night at LINE Corp. Dec 4, 2014 6
  • 7. Focuslight GrowthForecast の Ruby クローン » GrowthForecast は様々な値を WebAPI 経由でグ ラフ化できる Web ツールです。 » シンプルな API でリアルタイムにグラフを作成、更 新でき、Web インターフェイスからグラフの表示をカ スタマイズしたり、複数のメトリクスを重ね合わせた グラフを作成できます。 GrowthForecast - Lightning fast Graphing / Visualization より引用 validation night at LINE Corp. Dec 4, 2014 7
  • 8. focuslight-validator » Focuslight で使われている validator module » 汎用的に使うことが出来るように書かれている » RubyGems からカンタンインストール! $ gem i focuslight-validator validation night at LINE Corp. Dec 4, 2014 8
  • 9. with Sinatra require 'json' require 'sinatra/base' require 'focuslight-validator' class App < Sinatra::Base helpers do def validate(*args) Focuslight::Validator.validate(*args) end def rule(*args) Focuslight::Validator.rule(*args) end end post '/notice' do result = validate(params, message: { rule(:not_blank) }) halt 400, result.errors.to_json if result.has_error? # do anything... end end validation night at LINE Corp. Dec 4, 2014 9
  • 10. with Sinatra post '/notice' do # params[:message] がブランクではないかのチェック result = validate(params, message: { rule(:not_blank) }) # もしもブランクだったら、JSON 化したエラーメッセージを 400 で返す halt 400, result.errors.to_json if result.has_error? # do anything... end validation night at LINE Corp. Dec 4, 2014 10
  • 11. Result Class Focuslight::Validator.validate() の返り値 » Focuslight::Validator::Result のインスタ ンス p Focuslight::Validator::Result.instance_methods(false) #=> [:errors, :hash, :[], :[]=, :error, :has_error?] » [], []= が生えてる » そのまま Hash アクセス出来る validation night at LINE Corp. Dec 4, 2014 11
  • 12. Amazing!! validation night at LINE Corp. Dec 4, 2014 12
  • 13. Too easy!! validation night at LINE Corp. Dec 4, 2014 13
  • 14. Too simple!! validation night at LINE Corp. Dec 4, 2014 14
  • 15. built-in rules validation night at LINE Corp. Dec 4, 2014 15
  • 16. built-in rules 定義済みの内蔵ルール » not_blank, choice, int, uint, natural, float, double, real, int_range, bool, regexp これらのルールでは条件を満たせない場合 » lambda rule を使って解決(後で出てきます) https://github.com/focuslight/focuslight-validator/blob/master/lib/focuslight/ validator.rb#L121-L147 validation night at LINE Corp. Dec 4, 2014 16
  • 17. built-in rules (not_blank) nil か空白文字でなければ valid » strip された値が返る params = { v1: 'Foooo!!!! ', v2: '' } rule = Focuslight::Validator.rule(:not_blank) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v2=>"v2: missing or blank"} p result.hash #=> {:v1=>"Foooo!!!!"} validation night at LINE Corp. Dec 4, 2014 17
  • 18. built-in rules (choice) リストに含まれている値と一致すれば valid » そのままの値が返る params = { v1: 'yellow', v2: 'gold' } rule = Focuslight::Validator.rule(:choice, %w[ yellow red ]) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v2=>"v2: invalid value"} p result.hash #=> {:v1=>"yellow"} validation night at LINE Corp. Dec 4, 2014 18
  • 19. built-in rules (int) 整数であれば valid » to_i された値が返る params = { v1: '-3104', v2: '3.104' } rule = Focuslight::Validator.rule(:int) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v2=>"v2: invalid integer"} p result.hash #=> {:v1=>-3104} validation night at LINE Corp. Dec 4, 2014 19
  • 20. built-in rules (uint) 0 か自然数であれば valid » to_i された値が返る params = { v1: '3104', v2: '-3104' } rule = Focuslight::Validator.rule(:uint) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v2=>"v2: invalid integer (>= 0)"} p result.hash #=> {:v1=>3104} validation night at LINE Corp. Dec 4, 2014 20
  • 21. built-in rules (natural) 自然数であれば valid » to_i された値が返る params = { v1: '3104', v2: '0' } rule = Focuslight::Validator.rule(:natural) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v2=>"v2: invalid integer (>= 1)"} p result.hash #=> {:v1=>3104} validation night at LINE Corp. Dec 4, 2014 21
  • 22. built-in rules (float) 整数か小数(指数表記も含む)であれば valid » to_f された値が返る params = { v1: '3.104', v2: '3104', v3: '3.104e-03', v4: 'three' } rule = Focuslight::Validator.rule(:float) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, v3: { rule: rule }, v4: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v4=>"v4: invalid floating point num"} p result.hash #=> {:v1=>3.104, :v2=>3104.0, :v3=>0.003104} validation night at LINE Corp. Dec 4, 2014 22
  • 23. built-in rules (double) 整数か小数(指数表記も含む)であれば valid » to_f された値が返る params = { v1: '3.104', v2: '3104', v3: '3.104e-03', v4: 'three' } rule = Focuslight::Validator.rule(:double) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, v3: { rule: rule }, v4: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v4=>"v4: invalid floating point num"} p result.hash #=> {:v1=>3.104, :v2=>3104.0, :v3=>0.003104} validation night at LINE Corp. Dec 4, 2014 23
  • 24. built-in rules (real) 整数か小数(指数表記も含む)であれば valid » to_f された値が返る params = { v1: '3.104', v2: '3104', v3: '3.104e-03', v4: 'three' } rule = Focuslight::Validator.rule(:real) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, v3: { rule: rule }, v4: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v4=>"v4: invalid floating point num"} p result.hash #=> {:v1=>3.104, :v2=>3104.0, :v3=>0.003104} validation night at LINE Corp. Dec 4, 2014 24
  • 25. built-in rules (int_range) 指定範囲内の数値であれば valid » to_i された値が返る params = { v1: '3104', v2: '3.104', v3: '-1' } rule = Focuslight::Validator.rule(:int_range, 0..10000) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, v3: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v3=>"v3: invalid number in range 0..10000"} p result.hash #=> {:v1=>3104, :v2=>3} validation night at LINE Corp. Dec 4, 2014 25
  • 26. built-in rules (bool) true, false, 1, 0 のいずれかであれば valid » true か false が返る params = { v1: 'true', v2: '0', v3: 'FalseClass' } rule = Focuslight::Validator.rule(:bool) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, v3: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v3=>"v3: invalid bool value"} p result.hash #=> {:v1=>true, :v2=>false} validation night at LINE Corp. Dec 4, 2014 26
  • 27. built-in rules (regexp) 任意の正規表現にマッチすれば valid » そのままの値が返る params = { v1: 'Foooo!!!! ', v2: '' } rule = Focuslight::Validator.rule(:regexp, /^F.*/) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, ) p result.has_error? #=> true p result.errors #=> {:v2=>"v2: invalid input for pattern ^F.*"} p result.hash #=> {:v1=>"Foooo!!!! "} validation night at LINE Corp. Dec 4, 2014 27
  • 28. lambda rule validation night at LINE Corp. Dec 4, 2014 28
  • 29. lambda rule » built-in rules にない条件を使いたい場合 » lambda 式を自分で書く validation night at LINE Corp. Dec 4, 2014 29
  • 30. example of lambda rule message の文字数制限の validation params = { message: 'focuslight-validator is so awesome!!' } result = Focuslight::Validator.validate( params, message: { rule: Focuslight::Validator.rule( :lambda, ->(m) { m && (1..10000).include?(m.strip.length) }, 'invalid length', :strip ), }, ) p result.has_error? #=> false p result.errors #=> {} p result.hash #=> {:message=>"focuslight-validator is so awesome!!"} validation night at LINE Corp. Dec 4, 2014 30
  • 31. specifiable multiple rules validation night at LINE Corp. Dec 4, 2014 31
  • 32. specifiable multiple rules 複数のルールを指定することも出来る params = { v1: '10' } rule1 = Focuslight::Validator.rule(:not_blank) rule2 = Focuslight::Validator.rule(:int) result = Focuslight::Validator.validate( params, v1: { rule: [ rule1, rule2 ] }, ) p result.hash #=> {:v1=>10} validation night at LINE Corp. Dec 4, 2014 32
  • 33. specifiable multiple rules 複数のルールを指定する場合は順番に注意 1 params = { v1: '10', v2: '20' } rule1 = Focuslight::Validator.rule(:not_blank) rule2 = Focuslight::Validator.rule(:int) result = Focuslight::Validator.validate( params, v1: { rule: [ rule1, rule2 ] }, v2: { rule: [ rule2, rule1 ] }, ) # 後から指定したルールに基づく型変換がされるため、 # v2 は `to_i` されていない # エラーがある場合のメッセージも後から指定したルール優先 p result.hash #=> {:v1=>10, :v2=>"20"} 1 version 0.0.1 時点 validation night at LINE Corp. Dec 4, 2014 33
  • 34. validation types validation night at LINE Corp. Dec 4, 2014 34
  • 35. validation types single key, single value » 単一の value を持つデータの validation single key, array value » value に配列を持つデータの validation rule for combination of 2 or more params » 複数の values に対する複合的な validation validation night at LINE Corp. Dec 4, 2014 35
  • 36. validation types single key, single value params = { v1: nil, v2: nil, v3: nil } rule = Focuslight::Validator.rule(:int) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule, default: '100' }, v3: { rule: rule, excludable: true }, ) p result.has_error? #=> true p result.errors #=> {:v1=>"v1: invalid integer"} p result.hash #=> {:v2=>100, :v3=>nil} validation night at LINE Corp. Dec 4, 2014 36
  • 37. validation types single key, single value » default » 対象が nil だった場合のデフォルト値 » excludable » 対象が nil だった場合そのまま nil にする validation night at LINE Corp. Dec 4, 2014 37
  • 38. validation types single key, array value params = { v1: %w[ 10 20 30 ], v2: %w[ 3104 ] } rule = Focuslight::Validator.rule(:int) result = Focuslight::Validator.validate( params, v1: { array: true, rule: rule }, v2: { array: true, rule: rule, size: 5..10 }, v3: { array: true, rule: rule, excludable: true }, ) p result.has_error? #=> true p result.errors #=> {:v2=>"v2: doesn't have values specified: 5..10"} p result.hash #=> {:v1=>[10, 20, 30], :v3=>[]} validation night at LINE Corp. Dec 4, 2014 38
  • 39. validation types single key, array value » array » 配列を対象とした validation を行うかどうか » size » 許容する配列のサイズを Range で指定 » excludable » 対象が nil だった場合空の配列を埋める validation night at LINE Corp. Dec 4, 2014 39
  • 40. validation types rule for combination of 2 or more params params = { v1: '10', v2: '20', v3: '30' } rule = Focuslight::Validator.rule(:int) result = Focuslight::Validator.validate( params, v1: { rule: rule }, v2: { rule: rule }, v3: { rule: rule }, [ :v1, :v2, :v3 ] => { rule: Focuslight::Validator::Rule.new( -> (x, y, z) { x.to_i + y.to_i + z.to_i < 15 }, 'too large' ) }, ) p result.has_error? #=> true p result.errors #=> {:"v1,v2,v3"=>"v1,v2,v3: too large"} p result.hash #=> {:v1=>10, :v2=>20, :v3=>30} validation night at LINE Corp. Dec 4, 2014 40
  • 41. validation types rule for combination of 2 or more params » 複数の values に対する複合的な validation » 指定した values の合計値をチェックしたいなど » 返り値のオブジェクトには values が含まれない » 含めたい場合は通例どおり value 個別に定義 validation night at LINE Corp. Dec 4, 2014 41
  • 42. validation types rule for combination of 2 or more params » built-in rules も lambda rule も使えない » values の個数分を引数として取る Focuslight::Validator::Rule のインスタンス を定義して渡してあげる必要がある Focuslight::Validator::Rule.new( -> (x, y, z) { x.to_i + y.to_i + z.to_i < 15 }, 'too large' ) validation night at LINE Corp. Dec 4, 2014 42
  • 43. it is roughly like this validation night at LINE Corp. Dec 4, 2014 43
  • 44. fin. validation night at LINE Corp. Dec 4, 2014 44