Class: OandaAPI::Client::NamespaceProxy

Inherits:
Object
  • Object
show all
Defined in:
lib/oanda_api/client/namespace_proxy.rb

Overview

A client proxy and method-chaining enabler.

Examples:

Example usage

client  = OandaAPI::Client::TokenClient.new :practice, token
 = client.(1234) # => OandaAPI::Client::NamespaceProxy
.get                    # => OandaAPI::Resource::Account
.orders.get             # => OandaAPI::Resource::ResourceCollection

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, namespace_segment, conditions) ⇒ NamespaceProxy

Returns a new instance of NamespaceProxy.

Parameters:

  • client (OandaAPI::Client)
  • namespace_segment (String)

    a segment in a resource's URI. An ordered list of segments, joined, creates a path to a resource URI.

  • conditions (Hash)

    an optional list of parameters that typically specifies conditions and filters for a resource request. A "key" or "id" is a condition that identifies a particular resource. If a key condition is included, it is extracted and added as a namespace segment. See #extract_key_and_conditions.



31
32
33
34
35
36
37
38
39
40
# File 'lib/oanda_api/client/namespace_proxy.rb', line 31

def initialize(client, namespace_segment, conditions)
  fail ArgumentError, "expecting an OandaAPI::Client instance" unless
    client && client.is_a?(OandaAPI::Client) || client.is_a?(OandaAPI::Streaming::Client)
  fail ArgumentError, "expecting a namespace value" if namespace_segment.to_s.empty?

  @client = client
  @conditions = {}
  @namespace_segments = [ResourceBase.pluralize(namespace_segment)]
  extract_key_and_conditions conditions
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args) {|OandaAPI::ResourceBase| ... } ⇒ void, ...

Executes an API request and returns a resource object, or returns a clone of self for method chaining.

Yields:

Returns:



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/oanda_api/client/namespace_proxy.rb', line 104

def method_missing(sym, *args, &block)
  # Check for terminating method
  if [:create, :close, :delete, :get, :update, :stream].include?(sym)
    @client.execute_request sym, namespace, conditions, &block
  else
    ns = self.clone
    ns.namespace_segments << ResourceBase.pluralize(sym)
    ns.extract_key_and_conditions args.first
    ns
  end
end

Instance Attribute Details

#conditionsHash

Returns a collection of parameters that typically specifies conditions and filters for a resource request.

Returns:

  • (Hash)

    a collection of parameters that typically specifies conditions and filters for a resource request.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
# File 'lib/oanda_api/client/namespace_proxy.rb', line 18

class NamespaceProxy
  attr_accessor :conditions, :namespace_segments

  # @param [OandaAPI::Client] client
  #
  # @param [String] namespace_segment a _segment_ in a resource's URI. An
  #   ordered list of segments, joined, creates a path to a resource URI.
  #
  # @param [Hash] conditions an optional list of parameters that typically
  #   specifies conditions and filters for a resource request. A _"key"_
  #   or _"id"_ is a condition that identifies a particular resource. If a
  #   key condition is included, it is extracted and added as a namespace
  #   segment. See {#extract_key_and_conditions}.
  def initialize(client, namespace_segment, conditions)
    fail ArgumentError, "expecting an OandaAPI::Client instance" unless
      client && client.is_a?(OandaAPI::Client) || client.is_a?(OandaAPI::Streaming::Client)
    fail ArgumentError, "expecting a namespace value" if namespace_segment.to_s.empty?

    @client = client
    @conditions = {}
    @namespace_segments = [ResourceBase.pluralize(namespace_segment)]
    extract_key_and_conditions conditions
  end

  # Returns a deep clone of `self`.
  # @return [NamespaceProxy]
  def clone
    ns = self.dup
    ns.conditions = conditions.dup
    ns.namespace_segments = namespace_segments.dup
    ns
  end

  # Returns the namespace (URI path to a resource).
  # @return [String]
  def namespace
    "/" + @namespace_segments.join("/")
  end

  # Extracts a _key_ parameter from the arguments.
  # If a key is found, it's appended to the list namespace segments. Non-key
  # parameters are merged into the {#conditions} collection. A parameter is a
  # key if it's named ":id", or if there is only a single scalar argument.
  #
  # @example "key" parameters
  #  client  = OandaAPI::Client::TokenClient.new :practice, token
  #  account = client.account(1234)                  # 1234 is a _key_ (accountId)
  #  account.namespace                               # => /accounts/1234
  #
  #  order = account.order(instrument: "USD_JPY",
  #                              type: "market",
  #                             units: 10_000,
  #                              side: "buy").create # No key parameters here
  #
  #  position = account.position("USD_JPY").get      # USD_JPY is a key
  #
  # @param conditions either a hash of parameter values, single scalar value, or nil.
  #
  # @return [void]
  def extract_key_and_conditions(conditions)
    key =
      case
      when conditions && conditions.is_a?(Hash)
        @conditions.merge! Utils.rubyize_keys(conditions)
        @conditions.delete :id
      when conditions
        conditions
      end
    @namespace_segments << key if key
  end

  # Executes an API request and returns a resource object, or returns a
  # clone of `self` for method chaining.
  #
  # @yield [OandaAPI::ResourceBase] if the method is `:stream`.
  #
  # @return [void] if the method is `:stream`.
  #
  # @return [OandaAPI::Client::NamespaceProxy] if the method is used
  #   for chaining.
  #
  # @return [OandaAPI::ResourceBase] if the method is one of the supported
  #   _terminating_ methods (`:create`, `:close`, `:delete`, `:get`, `:update`).
  #
  # @return [OandaAPI::ResourceCollection] if the method is `:get` and the
  #   API returns a collection of resources.
  def method_missing(sym, *args, &block)
    # Check for terminating method
    if [:create, :close, :delete, :get, :update, :stream].include?(sym)
      @client.execute_request sym, namespace, conditions, &block
    else
      ns = self.clone
      ns.namespace_segments << ResourceBase.pluralize(sym)
      ns.extract_key_and_conditions args.first
      ns
    end
  end
end

#namespace_segmentsArray<String>

Returns an ordered list of namespaces, when joined, creates a path to a resource URI.

Returns:

  • (Array<String>)

    an ordered list of namespaces, when joined, creates a path to a resource URI.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
# File 'lib/oanda_api/client/namespace_proxy.rb', line 18

class NamespaceProxy
  attr_accessor :conditions, :namespace_segments

  # @param [OandaAPI::Client] client
  #
  # @param [String] namespace_segment a _segment_ in a resource's URI. An
  #   ordered list of segments, joined, creates a path to a resource URI.
  #
  # @param [Hash] conditions an optional list of parameters that typically
  #   specifies conditions and filters for a resource request. A _"key"_
  #   or _"id"_ is a condition that identifies a particular resource. If a
  #   key condition is included, it is extracted and added as a namespace
  #   segment. See {#extract_key_and_conditions}.
  def initialize(client, namespace_segment, conditions)
    fail ArgumentError, "expecting an OandaAPI::Client instance" unless
      client && client.is_a?(OandaAPI::Client) || client.is_a?(OandaAPI::Streaming::Client)
    fail ArgumentError, "expecting a namespace value" if namespace_segment.to_s.empty?

    @client = client
    @conditions = {}
    @namespace_segments = [ResourceBase.pluralize(namespace_segment)]
    extract_key_and_conditions conditions
  end

  # Returns a deep clone of `self`.
  # @return [NamespaceProxy]
  def clone
    ns = self.dup
    ns.conditions = conditions.dup
    ns.namespace_segments = namespace_segments.dup
    ns
  end

  # Returns the namespace (URI path to a resource).
  # @return [String]
  def namespace
    "/" + @namespace_segments.join("/")
  end

  # Extracts a _key_ parameter from the arguments.
  # If a key is found, it's appended to the list namespace segments. Non-key
  # parameters are merged into the {#conditions} collection. A parameter is a
  # key if it's named ":id", or if there is only a single scalar argument.
  #
  # @example "key" parameters
  #  client  = OandaAPI::Client::TokenClient.new :practice, token
  #  account = client.account(1234)                  # 1234 is a _key_ (accountId)
  #  account.namespace                               # => /accounts/1234
  #
  #  order = account.order(instrument: "USD_JPY",
  #                              type: "market",
  #                             units: 10_000,
  #                              side: "buy").create # No key parameters here
  #
  #  position = account.position("USD_JPY").get      # USD_JPY is a key
  #
  # @param conditions either a hash of parameter values, single scalar value, or nil.
  #
  # @return [void]
  def extract_key_and_conditions(conditions)
    key =
      case
      when conditions && conditions.is_a?(Hash)
        @conditions.merge! Utils.rubyize_keys(conditions)
        @conditions.delete :id
      when conditions
        conditions
      end
    @namespace_segments << key if key
  end

  # Executes an API request and returns a resource object, or returns a
  # clone of `self` for method chaining.
  #
  # @yield [OandaAPI::ResourceBase] if the method is `:stream`.
  #
  # @return [void] if the method is `:stream`.
  #
  # @return [OandaAPI::Client::NamespaceProxy] if the method is used
  #   for chaining.
  #
  # @return [OandaAPI::ResourceBase] if the method is one of the supported
  #   _terminating_ methods (`:create`, `:close`, `:delete`, `:get`, `:update`).
  #
  # @return [OandaAPI::ResourceCollection] if the method is `:get` and the
  #   API returns a collection of resources.
  def method_missing(sym, *args, &block)
    # Check for terminating method
    if [:create, :close, :delete, :get, :update, :stream].include?(sym)
      @client.execute_request sym, namespace, conditions, &block
    else
      ns = self.clone
      ns.namespace_segments << ResourceBase.pluralize(sym)
      ns.extract_key_and_conditions args.first
      ns
    end
  end
end

Instance Method Details

#cloneNamespaceProxy

Returns a deep clone of self.

Returns:



44
45
46
47
48
49
# File 'lib/oanda_api/client/namespace_proxy.rb', line 44

def clone
  ns = self.dup
  ns.conditions = conditions.dup
  ns.namespace_segments = namespace_segments.dup
  ns
end

#extract_key_and_conditions(conditions) ⇒ void

This method returns an undefined value.

Extracts a key parameter from the arguments. If a key is found, it's appended to the list namespace segments. Non-key parameters are merged into the #conditions collection. A parameter is a key if it's named ":id", or if there is only a single scalar argument.

Examples:

"key" parameters

client  = OandaAPI::Client::TokenClient.new :practice, token
 = client.(1234)                  # 1234 is a _key_ (accountId)
.namespace                               # => /accounts/1234

order = .order(instrument: "USD_JPY",
                            type: "market",
                           units: 10_000,
                            side: "buy").create # No key parameters here

position = .position("USD_JPY").get      # USD_JPY is a key

Parameters:

  • conditions

    either a hash of parameter values, single scalar value, or nil.



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/oanda_api/client/namespace_proxy.rb', line 77

def extract_key_and_conditions(conditions)
  key =
    case
    when conditions && conditions.is_a?(Hash)
      @conditions.merge! Utils.rubyize_keys(conditions)
      @conditions.delete :id
    when conditions
      conditions
    end
  @namespace_segments << key if key
end

#namespaceString

Returns the namespace (URI path to a resource).

Returns:

  • (String)


53
54
55
# File 'lib/oanda_api/client/namespace_proxy.rb', line 53

def namespace
  "/" + @namespace_segments.join("/")
end