Module: Praxis::EndpointDefinition::ClassMethods
- Defined in:
- lib/praxis/endpoint_definition.rb
Instance Attribute Summary collapse
-
#actions ⇒ Object
readonly
Returns the value of attribute actions.
-
#controller ⇒ Object
Returns the value of attribute controller.
-
#metadata ⇒ Object
readonly
opaque hash of user-defined medata, used to decorate the definition, and also available in the generated JSON documents.
-
#parent_prefix ⇒ Object
readonly
Returns the value of attribute parent_prefix.
-
#responses ⇒ Object
readonly
Returns the value of attribute responses.
- #routing_prefix ⇒ Object
-
#traits ⇒ Object
readonly
Returns the value of attribute traits.
-
#version_options ⇒ Object
readonly
Returns the value of attribute version_options.
-
#version_prefix ⇒ Object
readonly
Returns the value of attribute version_prefix.
Instance Method Summary collapse
- #action(name, &block) ⇒ Object
- #action_defaults(&block) ⇒ Object
- #canonical_path(action_name = nil) ⇒ Object
- #describe(context: nil) ⇒ Object
- #description(text = nil) ⇒ Object
- #display_name(string = nil) ⇒ Object
- #id ⇒ Object
- #inherit_params_from_parent(parent_action, **mapping) ⇒ Object
- #media_type(media_type = nil) ⇒ Object
- #nodoc! ⇒ Object
- #on_finalize(&block) ⇒ Object
- #parent(parent = nil, **mapping) ⇒ Object
- #parse_href(path) ⇒ Object
- #prefix(prefix = nil) ⇒ Object
- #to_href(params) ⇒ Object
- #trait(trait_name) ⇒ Object (also: #use)
- #version(version = nil) ⇒ Object
Instance Attribute Details
#actions ⇒ Object (readonly)
Returns the value of attribute actions.
69 70 71 |
# File 'lib/praxis/endpoint_definition.rb', line 69 def actions @actions end |
#controller ⇒ Object
Returns the value of attribute controller.
75 76 77 |
# File 'lib/praxis/endpoint_definition.rb', line 75 def controller @controller end |
#metadata ⇒ Object (readonly)
opaque hash of user-defined medata, used to decorate the definition, and also available in the generated JSON documents
73 74 75 |
# File 'lib/praxis/endpoint_definition.rb', line 73 def @metadata end |
#parent_prefix ⇒ Object (readonly)
Returns the value of attribute parent_prefix.
69 70 71 |
# File 'lib/praxis/endpoint_definition.rb', line 69 def parent_prefix @parent_prefix end |
#responses ⇒ Object (readonly)
Returns the value of attribute responses.
69 70 71 |
# File 'lib/praxis/endpoint_definition.rb', line 69 def responses @responses end |
#routing_prefix ⇒ Object
162 163 164 165 166 |
# File 'lib/praxis/endpoint_definition.rb', line 162 def routing_prefix return @routing_prefix if @routing_prefix @routing_prefix = parent_prefix + prefix end |
#traits ⇒ Object (readonly)
Returns the value of attribute traits.
69 70 71 |
# File 'lib/praxis/endpoint_definition.rb', line 69 def traits @traits end |
#version_options ⇒ Object (readonly)
Returns the value of attribute version_options.
69 70 71 |
# File 'lib/praxis/endpoint_definition.rb', line 69 def @version_options end |
#version_prefix ⇒ Object (readonly)
Returns the value of attribute version_prefix.
69 70 71 |
# File 'lib/praxis/endpoint_definition.rb', line 69 def version_prefix @version_prefix end |
Instance Method Details
#action(name, &block) ⇒ Object
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/praxis/endpoint_definition.rb', line 222 def action(name, &block) raise ArgumentError, 'can not create ActionDefinition without block' unless block_given? raise ArgumentError, "Action names must be defined using symbols (Got: #{name} (of type #{name.class}))" unless name.is_a? Symbol action = ActionDefinition.new(name, self, &block) if action.sister_post_action post_path = \ if action.sister_post_action == true "#{action.route.prefixed_path}/actions/#{action.name}" elsif action.sister_post_action.start_with?('//') action.sister_post_action # Avoid appending prefix else # Make sure to cleanup the leading '/' if any, as we're always adding it below cleaned_path = action.sister_post_action.start_with?('/') ? action.sister_post_action[1..] : action.sister_post_action "#{action.route.prefixed_path}/#{cleaned_path}" end # Save the finalization of the twin POST actions once we've loaded the endpoint definition on_finalize do # Create the sister POST action with a payload matching the original params post_action = action.clone_action_as_post(at: post_path) @actions[post_action.name] = post_action end end @actions[name] = action end |
#action_defaults(&block) ⇒ Object
216 217 218 219 220 |
# File 'lib/praxis/endpoint_definition.rb', line 216 def action_defaults(&block) @action_defaults.instance_eval(&block) if block_given? @action_defaults end |
#canonical_path(action_name = nil) ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/praxis/endpoint_definition.rb', line 175 def canonical_path(action_name = nil) if action_name raise "Canonical path for #{name} is already defined as: '#{@canonical_action_name}'. 'canonical_path' can only be defined once." if @canonical_action_name @canonical_action_name = action_name else # Resolution of the actual action definition needs to be done lazily, since we can use the `canonical_path` stanza # at the top of the resource, well before the actual action is defined. unless @canonical_action href_action = @canonical_action_name || DEFAULT_RESOURCE_HREF_ACTION @canonical_action = actions.fetch(href_action) do raise "Error: trying to set canonical_href of #{name}. Action '#{href_action}' does not exist" end end @canonical_action end end |
#describe(context: nil) ⇒ Object
258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/praxis/endpoint_definition.rb', line 258 def describe(context: nil) {}.tap do |hash| hash[:description] = description hash[:media_type] = media_type.describe(true) if media_type hash[:actions] = actions.values.collect { |action| action.describe(context: context) } hash[:name] = name hash[:parent] = parent.id if parent hash[:display_name] = display_name hash[:metadata] = hash[:traits] = traits end end |
#description(text = nil) ⇒ Object
249 250 251 252 |
# File 'lib/praxis/endpoint_definition.rb', line 249 def description(text = nil) @description = text if text @description end |
#display_name(string = nil) ⇒ Object
77 78 79 80 81 82 83 |
# File 'lib/praxis/endpoint_definition.rb', line 77 def display_name(string = nil) unless string return @display_name ||= name.split('::').last # Best guess at a display name? end @display_name = string end |
#id ⇒ Object
254 255 256 |
# File 'lib/praxis/endpoint_definition.rb', line 254 def id name.gsub('::', '-') end |
#inherit_params_from_parent(parent_action, **mapping) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/praxis/endpoint_definition.rb', line 146 def inherit_params_from_parent(parent_action, **mapping) actions.each do |_name, action| action.params do mapping.each do |parent_name, name| next if action.params&.attributes&.key?(name) parent_attribute = parent_action.params.attributes[parent_name] attribute name, parent_attribute.type, **parent_attribute. end end end end |
#media_type(media_type = nil) ⇒ Object
98 99 100 101 102 103 |
# File 'lib/praxis/endpoint_definition.rb', line 98 def media_type(media_type = nil) return @media_type if media_type.nil? media_type = SimpleMediaType.new(media_type) if media_type.is_a?(String) @media_type = media_type end |
#nodoc! ⇒ Object
271 272 273 |
# File 'lib/praxis/endpoint_definition.rb', line 271 def nodoc! [:doc_visibility] = :none end |
#on_finalize(&block) ⇒ Object
85 86 87 88 89 |
# File 'lib/praxis/endpoint_definition.rb', line 85 def on_finalize(&block) @on_finalize << proc(&block) if block_given? @on_finalize end |
#parent(parent = nil, **mapping) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/praxis/endpoint_definition.rb', line 105 def parent(parent = nil, **mapping) return @parent if parent.nil? @routing_prefix = nil # reset routing_prefix parent_action = parent.canonical_path parent_route = parent_action.route.path # if a mapping is passed, it *must* resolve any param name conflicts unless mapping.any? # assume last capture is the relevant one to replace # if not... then I quit. parent_param_name = parent_route.names.last # more assumptions about names parent_name = parent.name.demodulize.underscore.singularize # put it together to find what we should call this new param param = "#{parent_name}_#{parent_param_name}".to_sym mapping[parent_param_name.to_sym] = param end # complete the mapping and massage the route parent_route.names.collect(&:to_sym).each do |name| if mapping.key?(name) param = mapping[name] # FIXME: this won't handle URI Template type paths, ie '/{parent_id}' prefixed_path = parent_action.route.prefixed_path @parent_prefix = prefixed_path.gsub(/(:)(#{name})(\W+|$)/, "\\1#{param}\\3") else mapping[name] = name end end on_finalize do inherit_params_from_parent(parent_action, **mapping) end @parent = parent end |
#parse_href(path) ⇒ Object
197 198 199 200 201 202 203 204 205 206 |
# File 'lib/praxis/endpoint_definition.rb', line 197 def parse_href(path) path = path.path if path.is_a?(::URI::Generic) param_values = canonical_path.route.path.params(path) attrs = canonical_path.params.attributes param_values.each_with_object({}) do |(key, value), hash| hash[key.to_sym] = attrs[key.to_sym].load(value, [key]) end rescue StandardError => e raise Praxis::Exception, "Error parsing or coercing parameters from href: #{path}\n" + e. end |
#prefix(prefix = nil) ⇒ Object
91 92 93 94 95 96 |
# File 'lib/praxis/endpoint_definition.rb', line 91 def prefix(prefix = nil) return @prefix if prefix.nil? @routing_prefix = nil # reset routing_prefix @prefix = prefix end |
#to_href(params) ⇒ Object
193 194 195 |
# File 'lib/praxis/endpoint_definition.rb', line 193 def to_href(params) canonical_path.route.path.(params.transform_values(&:to_s)) end |
#trait(trait_name) ⇒ Object Also known as: use
208 209 210 211 212 213 |
# File 'lib/praxis/endpoint_definition.rb', line 208 def trait(trait_name) raise Exceptions::InvalidTrait, "Trait #{trait_name} not found in the system" unless ApiDefinition.instance.traits.key? trait_name # TODO: We're only storing the names here, should we store the actual traits in a hash? @traits << trait_name end |
#version(version = nil) ⇒ Object
168 169 170 171 172 173 |
# File 'lib/praxis/endpoint_definition.rb', line 168 def version(version = nil) return @version unless version @version = version @action_defaults.instance_eval(&EndpointDefinition.generate_defaults_block(version: version)) end |