Class: Twirp::Service

Inherits:
Object
  • Object
show all
Extended by:
ServiceDSL
Defined in:
lib/twirp/service.rb

Class Attribute Summary collapse

Instance Method Summary collapse

Methods included from ServiceDSL

package, package_name, rpc, rpcs, service, service_full_name, service_name

Constructor Details

#initialize(handler) ⇒ Service



19
20
21
22
23
24
25
26
# File 'lib/twirp/service.rb', line 19

def initialize(handler)
  @handler = handler

  @before = []
  @on_success = []
  @on_error = []
  @exception_raised = []
end

Class Attribute Details

.raise_exceptionsObject

Raise exceptions instead of handling them with exception_raised hooks. Useful during tests to easily debug and catch unexpected exceptions. Default false.



16
17
18
# File 'lib/twirp/service.rb', line 16

def raise_exceptions
  @raise_exceptions
end

Instance Method Details

#before(&block) ⇒ Object

Setup hook blocks.



29
# File 'lib/twirp/service.rb', line 29

def before(&block) @before << block; end

#call(rack_env) ⇒ Object

Rack app handler.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/twirp/service.rb', line 39

def call(rack_env)
  begin
    env = {}
    bad_route = route_request(rack_env, env)
    return error_response(bad_route, env) if bad_route

    @before.each do |hook|
      result = hook.call(rack_env, env)
      return error_response(result, env) if result.is_a? Twirp::Error
    end

    output = call_handler(env)
    return error_response(output, env) if output.is_a? Twirp::Error
    return success_response(output, env)

  rescue => e
    raise e if self.class.raise_exceptions
    begin
      @exception_raised.each{|hook| hook.call(e, env) }
    rescue => hook_e
      e = hook_e
    end

    twerr = Twirp::Error.internal_with(e)
    return error_response(twerr, env)
  end
end

#call_rpc(rpc_method, input = {}, env = {}) ⇒ Object

Call the handler method with input attributes or protobuf object. Returns a proto object (response) or a Twirp::Error. Hooks are not called and exceptions are raised instead of being wrapped. This is useful for unit testing the handler. The env should include fake data that is used by the handler, replicating middleware and before hooks.



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/twirp/service.rb', line 72

def call_rpc(rpc_method, input={}, env={})
  base_env = self.class.rpcs[rpc_method.to_s]
  return Twirp::Error.bad_route("Invalid rpc method #{rpc_method.to_s.inspect}") unless base_env

  env = env.merge(base_env)
  input = env[:input_class].new(input) if input.is_a? Hash
  env[:input] = input
  env[:content_type] ||= Encoding::PROTO
  env[:http_response_headers] = {}
  call_handler(env)
end

#exception_raised(&block) ⇒ Object



32
# File 'lib/twirp/service.rb', line 32

def exception_raised(&block) @exception_raised << block; end

#full_nameObject

Service full_name is needed to route http requests to this service.



35
# File 'lib/twirp/service.rb', line 35

def full_name; @full_name ||= self.class.service_full_name; end

#nameObject



36
# File 'lib/twirp/service.rb', line 36

def name; @name ||= self.class.service_name; end

#on_error(&block) ⇒ Object



31
# File 'lib/twirp/service.rb', line 31

def on_error(&block) @on_error << block; end

#on_success(&block) ⇒ Object



30
# File 'lib/twirp/service.rb', line 30

def on_success(&block) @on_success << block; end