Class: Karafka::Core::Contractable::Contract

Inherits:
Object
  • Object
show all
Extended by:
Karafka::Core::Configurable
Defined in:
lib/karafka/core/contractable/contract.rb

Overview

Note:

This contract does NOT support rules inheritance as it was never needed in Karafka

Base contract for all the contracts that check data format

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Karafka::Core::Configurable

extended, included

Class Attribute Details

.rulesArray<Rule> (readonly)

Returns all the validation rules defined for a given contract.

Returns:

  • (Array<Rule>)

    all the validation rules defined for a given contract



30
31
32
# File 'lib/karafka/core/contractable/contract.rb', line 30

def rules
  @rules
end

Class Method Details

.nested(path) ⇒ Object

Allows for definition of a scope/namespace for nested validations

Examples:

nested(:key) do
  required(:inside) { |inside| inside.is_a?(String) }
end

Parameters:

  • path (Symbol)

    path in the hash for nesting



40
41
42
43
44
45
# File 'lib/karafka/core/contractable/contract.rb', line 40

def nested(path, &)
  init_accu
  @nested << path
  instance_eval(&)
  @nested.pop
end

.optional(*keys, &block) ⇒ Object

Parameters:

  • keys (Array<Symbol>)

    single or full path

  • block (Proc)

    validation rule



59
60
61
62
# File 'lib/karafka/core/contractable/contract.rb', line 59

def optional(*keys, &block)
  init_accu
  @rules << Rule.new(@nested + keys, :optional, block).freeze
end

.required(*keys, &block) ⇒ Object

Defines a rule for a required field (required means, that will automatically create an error if missing)

Parameters:

  • keys (Array<Symbol>)

    single or full path

  • block (Proc)

    validation rule



52
53
54
55
# File 'lib/karafka/core/contractable/contract.rb', line 52

def required(*keys, &block)
  init_accu
  @rules << Rule.new(@nested + keys, :required, block).freeze
end

.virtual(&block) ⇒ Object

Note:

Virtual rules have different result expectations. Please see contracts or specs for details.

Parameters:

  • block (Proc)

    validation rule



68
69
70
71
# File 'lib/karafka/core/contractable/contract.rb', line 68

def virtual(&block)
  init_accu
  @rules << Rule.new([], :virtual, block).freeze
end

Instance Method Details

#call(data, scope: EMPTY_ARRAY) ⇒ Result

Runs the validation

Parameters:

  • data (Hash)

    hash with data we want to validate

  • scope (Array<String>) (defaults to: EMPTY_ARRAY)

    scope of this contract (if any) or empty array if no parent scope is needed if contract starts from root

Returns:

  • (Result)

    validaton result



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/karafka/core/contractable/contract.rb', line 88

def call(data, scope: EMPTY_ARRAY)
  errors = []

  self.class.rules.each do |rule|
    case rule.type
    when :required
      validate_required(data, rule, errors, scope)
    when :optional
      validate_optional(data, rule, errors, scope)
    when :virtual
      validate_virtual(data, rule, errors, scope)
    end
  end

  return Result.success if errors.empty?

  Result.new(errors, self)
end

#validate!(data, error_class, scope: EMPTY_ARRAY) ⇒ Boolean

Returns true.

Parameters:

  • data (Hash)

    data for validation

  • error_class (Class)

    error class that should be used when validation fails

  • scope (Array<String>) (defaults to: EMPTY_ARRAY)

    scope of this contract (if any) or empty array if no parent scope is needed if contract starts from root

Returns:

  • (Boolean)

    true

Raises:

  • (StandardError)

    any error provided in the error_class that inherits from the standard error



114
115
116
117
118
119
120
# File 'lib/karafka/core/contractable/contract.rb', line 114

def validate!(data, error_class, scope: EMPTY_ARRAY)
  result = call(data, scope: scope)

  return true if result.success?

  raise error_class, result.errors
end