Class: CommandTower::Clients::EndpointBase

Inherits:
Object
  • Object
show all
Defined in:
app/services/command_tower/clients/endpoint_base.rb

Constant Summary collapse

AUTHENTICATION_MODES =
%i[required none].freeze

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client:) ⇒ EndpointBase

Returns a new instance of EndpointBase.



74
75
76
77
78
# File 'app/services/command_tower/clients/endpoint_base.rb', line 74

def initialize(client:)
  raise Errors::ConfigurationError, "client is required" if client.nil?

  @client = client
end

Class Attribute Details

.declared_authenticationObject (readonly)

Returns the value of attribute declared_authentication.



9
10
11
# File 'app/services/command_tower/clients/endpoint_base.rb', line 9

def declared_authentication
  @declared_authentication
end

.declared_http_methodObject (readonly)

Returns the value of attribute declared_http_method.



9
10
11
# File 'app/services/command_tower/clients/endpoint_base.rb', line 9

def declared_http_method
  @declared_http_method
end

.declared_input_classObject (readonly)

Returns the value of attribute declared_input_class.



9
10
11
# File 'app/services/command_tower/clients/endpoint_base.rb', line 9

def declared_input_class
  @declared_input_class
end

.declared_pathObject (readonly)

Returns the value of attribute declared_path.



9
10
11
# File 'app/services/command_tower/clients/endpoint_base.rb', line 9

def declared_path
  @declared_path
end

.declared_request_serializerObject (readonly)

Returns the value of attribute declared_request_serializer.



9
10
11
# File 'app/services/command_tower/clients/endpoint_base.rb', line 9

def declared_request_serializer
  @declared_request_serializer
end

.declared_response_deserializerObject (readonly)

Returns the value of attribute declared_response_deserializer.



9
10
11
# File 'app/services/command_tower/clients/endpoint_base.rb', line 9

def declared_response_deserializer
  @declared_response_deserializer
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



72
73
74
# File 'app/services/command_tower/clients/endpoint_base.rb', line 72

def client
  @client
end

Class Method Details

.authentication(mode) ⇒ Object

Default when omitted: :required. Public endpoints must opt out with :none.



56
57
58
59
60
61
62
63
64
65
# File 'app/services/command_tower/clients/endpoint_base.rb', line 56

def authentication(mode)
  normalized = mode.to_sym
  unless AUTHENTICATION_MODES.include?(normalized)
    raise Errors::ConfigurationError,
          "#{name} authentication must be one of " \
          "#{AUTHENTICATION_MODES.join(', ')} (got: #{mode.inspect})"
  end

  @declared_authentication = normalized
end

.authentication_modeObject



67
68
69
# File 'app/services/command_tower/clients/endpoint_base.rb', line 67

def authentication_mode
  declared_authentication || :required
end

.http_method(method) ⇒ Object



13
14
15
# File 'app/services/command_tower/clients/endpoint_base.rb', line 13

def http_method(method)
  @declared_http_method = Transport::Request.validate_method!(method)
end

.input(klass) ⇒ Object



26
27
28
29
30
31
32
33
# File 'app/services/command_tower/clients/endpoint_base.rb', line 26

def input(klass)
  unless klass.is_a?(Class)
    raise Errors::ConfigurationError,
          "#{name} input must be a Class (got: #{klass.inspect})"
  end

  @declared_input_class = klass
end

.path(value = nil, &block) ⇒ Object



17
18
19
20
21
22
23
24
# File 'app/services/command_tower/clients/endpoint_base.rb', line 17

def path(value = nil, &block)
  if block && !value.nil?
    raise Errors::ConfigurationError,
          "#{name} path must be a String or a block, not both"
  end

  @declared_path = block || value
end

.request_serializer(serializer) ⇒ Object



35
36
37
38
39
40
41
42
43
# File 'app/services/command_tower/clients/endpoint_base.rb', line 35

def request_serializer(serializer)
  unless serializer.respond_to?(:call)
    raise Errors::ConfigurationError,
          "#{name} request_serializer must respond to call " \
          "(got: #{serializer.inspect})"
  end

  @declared_request_serializer = serializer
end

.response_deserializer(deserializer) ⇒ Object



45
46
47
48
49
50
51
52
53
# File 'app/services/command_tower/clients/endpoint_base.rb', line 45

def response_deserializer(deserializer)
  unless deserializer.respond_to?(:call)
    raise Errors::ConfigurationError,
          "#{name} response_deserializer must respond to call " \
          "(got: #{deserializer.inspect})"
  end

  @declared_response_deserializer = deserializer
end

Instance Method Details

#call(**attributes) ⇒ Object

Internal orchestration — not the locked product invocation API. Builds input, serializes, executes, then deserializes a successful response into a top-level provider contract object or Array of contracts.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'app/services/command_tower/clients/endpoint_base.rb', line 83

def call(**attributes)
  assert_declarations!
  enforce_authentication_if_required!
  input = build_input!(attributes)
  path = resolve_path(input)
  serialized = serialize_request!(input)

  request = Transport::Request.build(
    method: self.class.declared_http_method,
    url: path,
    query: serialized.query,
    body: serialized.body,
    headers: serialized.headers
  )

  result = client.execute(request)
  return result if result.failure?

  deserialize_success!(result)
end