Class: Meta::Execution

Inherits:
Object
  • Object
show all
Defined in:
lib/meta/application/execution.rb

Defined Under Namespace

Modules: MakeToRackMiddleware Classes: Abort

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request) ⇒ Execution

Returns a new instance of Execution.



10
11
12
13
14
# File 'lib/meta/application/execution.rb', line 10

def initialize(request)
  @request = request
  @response = Rack::Response.new([], 0) # 状态码初始为 0,代表一个未设置状态
  @parameters = {}
end

Instance Attribute Details

#requestObject (readonly)

Returns the value of attribute request.



7
8
9
# File 'lib/meta/application/execution.rb', line 7

def request
  @request
end

#responseObject (readonly)

Returns the value of attribute response.



7
8
9
# File 'lib/meta/application/execution.rb', line 7

def response
  @response
end

#route_metaObject

Returns the value of attribute route_meta.



8
9
10
# File 'lib/meta/application/execution.rb', line 8

def route_meta
  @route_meta
end

Instance Method Details

#abort_execution!Object

Raises:



126
127
128
# File 'lib/meta/application/execution.rb', line 126

def abort_execution!
  raise Abort
end

#parametersObject



16
17
18
# File 'lib/meta/application/execution.rb', line 16

def parameters
  @_parameters || @_parameters = route_meta.parse_parameters(self)
end

#params(mode = :keep_missing) ⇒ Object

调用方式:

  • ‘params`:等价于 params(:keep_missing)

  • ‘params(:keep_missing)`

  • ‘params(:discard_missing)`

  • ‘params(:raw)`



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/meta/application/execution.rb', line 44

def params(mode = :keep_missing)
  @_params ||= {}
  return @_params[mode] if @_params.key?(mode)

  if mode == :raw
    @_params[:raw] = parse_raw_params.freeze
  else
    params = parameters
    params = params.merge(request_body(mode) || {}) if route_meta.request_body
    @_params[mode] = params
  end

  @_params[mode]
end

#render(*params) ⇒ Object

调用方式:

  • render(value, options?)

  • render(key, value, options?)



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/meta/application/execution.rb', line 63

def render(*params)
  if (params.length < 1 || params.length > 3)
    raise ArgumentError, "wrong number of arguments (given #{params.length} expected 1..3)"
  elsif params[0].is_a?(Symbol)
    key, value, options = params
  else
    key = :__root__
    value, options = params
  end

  @renders ||= {}
  raise '同一种 render 方式只能调用一次,请检查是否重复使用相同的 key 渲染,或者重复调用 render(value) 的方式' if @renders.key?(key)
  if key == :__root__ && @renders.keys.any? { |key| key != :__root__ }
    raise '已使用 render(:key, value) 的方式调用过,不能再使用 render(value) 的方式'
  elsif key != :__root__ && @renders.key?(:__root__)
    raise '已使用 render(value) 的方式调用过,不能再使用 render(:key, value) 的方式'
  end

  @renders[key] = { value: value, options: options || {} }
end

#render_entity(entity_schema) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/meta/application/execution.rb', line 84

def render_entity(entity_schema)
  # 首先获取 JSON 响应值
  renders = @renders || {}

  if renders.key?(:__root__) || renders.empty?
    # 从 root 角度获取
    if renders[:__root__]
      hash = renders[:__root__][:value]
      options = renders[:__root__][:options]
    else
      response_body = response.body ? response.body[0] : nil
      hash = response_body ? JSON.parse(response_body) : {}
      options = {}
    end

    new_hash = route_meta.render_entity(self, entity_schema, hash, options)
    response.content_type = 'application/json' if response.content_type.nil?
    response.body = [JSON.generate(new_hash)]
  else
    # 渲染多键值结点
    errors = {}
    final_value = {}
    renders.each do |key, render_content|
      raise Errors::RenderingError, "渲染的键名 `#{key}` 不存在,请检查实体定义以确认是否有拼写错误" unless entity_schema.properties.key?(key)
      schema = entity_schema.properties[key].staged(:render)
      final_value[key] = route_meta.render_entity(self, schema, render_content[:value], render_content[:options])
    rescue JsonSchema::ValidationErrors => e
      # 错误信息再度绑定 key
      errors.merge! e.errors.transform_keys! { |k| k.empty? ? key : "#{key}.#{k}" }
    end.to_h

    if errors.empty?
      response.content_type = 'application/json' if response.content_type.nil?
      response.body = [JSON.generate(final_value)]
    else
      raise Errors::RenderingInvalid.new(errors)
    end
  end
rescue JsonSchema::ValidationErrors => e
  raise Errors::RenderingInvalid.new(e.errors)
end

#request_body(mode = :keep_missing) ⇒ Object

调用方式:

  • ‘request_body`:等价于 request_body(:keep_missing)

  • ‘request_body(:keep_missing)`

  • ‘request_body(:discard_missing)`



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/meta/application/execution.rb', line 25

def request_body(mode = :keep_missing)
  @_request_body ||= {}

  case mode
  when :keep_missing
    @_request_body[:keep_missing] || @_request_body[:keep_missing] = route_meta.parse_request_body(self).freeze
  when :discard_missing
    @_request_body[:discard_missing] || @_request_body[:discard_missing] = route_meta.parse_request_body(self, discard_missing: true).freeze
  else
    raise NameError, "未知的 mode 参数:#{mode}"
  end
end