module Praxis::EndpointDefinition::ClassMethods
Attributes
opaque hash of user-defined medata, used to decorate the definition, and also available in the generated JSON documents
Public Instance Methods
Source
# 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
Source
# File lib/praxis/endpoint_definition.rb, line 216 def action_defaults(&block) @action_defaults.instance_eval(&block) if block_given? @action_defaults end
Source
# 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
Source
# 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] = metadata hash[:traits] = traits end end
Source
# File lib/praxis/endpoint_definition.rb, line 249 def description(text = nil) @description = text if text @description end
Source
# 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
Source
# 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.options end end end end
Source
# 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
Source
# File lib/praxis/endpoint_definition.rb, line 271 def nodoc! metadata[:doc_visibility] = :none end
Source
# File lib/praxis/endpoint_definition.rb, line 85 def on_finalize(&block) @on_finalize << proc(&block) if block_given? @on_finalize end
Source
# 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
Source
# 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.message end
Source
# 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
Source
# File lib/praxis/endpoint_definition.rb, line 162 def routing_prefix return @routing_prefix if @routing_prefix @routing_prefix = parent_prefix + prefix end
Source
# File lib/praxis/endpoint_definition.rb, line 193 def to_href(params) canonical_path.route.path.expand(params.transform_values(&:to_s)) end
Source
# 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
Also aliased as: use
Source
# 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