Class: Brainstem::ApiDocs::Endpoint

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Concerns::Formattable, Concerns::Optional
Defined in:
lib/brainstem/api_docs/endpoint.rb

Constant Summary collapse

ACTION_ORDER =
%w(index show create update delete)

Instance Attribute Summary collapse

Attributes included from Concerns::Formattable

#formatters

Instance Method Summary collapse

Methods included from Concerns::Formattable

#formatted_as, #formatter_type

Constructor Details

#initialize(atlas, options = {}) {|_self| ... } ⇒ Endpoint

Returns a new instance of Endpoint.

Yields:

  • (_self)

Yield Parameters:



31
32
33
34
35
# File 'lib/brainstem/api_docs/endpoint.rb', line 31

def initialize(atlas, options = {})
  self.atlas = atlas
  super options
  yield self if block_given?
end

Instance Attribute Details

#actionObject

Returns the value of attribute action.



37
38
39
# File 'lib/brainstem/api_docs/endpoint.rb', line 37

def action
  @action
end

#atlasObject

Returns the value of attribute atlas.



37
38
39
# File 'lib/brainstem/api_docs/endpoint.rb', line 37

def atlas
  @atlas
end

#controllerObject

Returns the value of attribute controller.



37
38
39
# File 'lib/brainstem/api_docs/endpoint.rb', line 37

def controller
  @controller
end

#controller_nameObject

Returns the value of attribute controller_name.



37
38
39
# File 'lib/brainstem/api_docs/endpoint.rb', line 37

def controller_name
  @controller_name
end

#http_methodsObject

Returns the value of attribute http_methods.



37
38
39
# File 'lib/brainstem/api_docs/endpoint.rb', line 37

def http_methods
  @http_methods
end

#include_internalObject

Returns the value of attribute include_internal.



37
38
39
# File 'lib/brainstem/api_docs/endpoint.rb', line 37

def include_internal
  @include_internal
end

#pathObject

Returns the value of attribute path.



37
38
39
# File 'lib/brainstem/api_docs/endpoint.rb', line 37

def path
  @path
end

#presenterObject

Stores the ApiDocs::Presenter object associated with this endpoint.



257
258
259
# File 'lib/brainstem/api_docs/endpoint.rb', line 257

def presenter
  @presenter
end

Instance Method Details

#<=>(other) ⇒ Object

Sorts this endpoint in comparison to other endpoints.

Follows a manually defined order of precedence (ACTION_ORDER). The earlier an action name appears on the list, the earlier it is sorted.

In the event that an action is not on the list, it is sorted after any listed routes, and then sorted alphabetically among the remainder.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/brainstem/api_docs/endpoint.rb', line 68

def <=>(other)

  # Any unordered routes are assigned an index of +ACTION_ORDER.count+.
  ordered_actions_count   = ACTION_ORDER.count
  own_action_priority     = ACTION_ORDER.index(action.to_s)       || ordered_actions_count
  other_action_priority   = ACTION_ORDER.index(other.action.to_s) || ordered_actions_count

  # If the priorities are unequal (i.e. one or both are named; duplicates
  # should not exist for named routes):
  if own_action_priority != other_action_priority

    # Flip order if this action's priority is greater than the other.
    # other_action_priority <=> own_action_priority
    own_action_priority <=> other_action_priority

  # If the priorities are equal, i.e. both not in the list:
  else

    # Flip order if this action's name is alphabetically later.
    action.to_s <=> other.action.to_s
  end
end

#action_configurationObject

Helper for retrieving action-specific configuration from the controller.



272
273
274
# File 'lib/brainstem/api_docs/endpoint.rb', line 272

def action_configuration
  configuration[action] || {}
end

#consumesObject



122
123
124
# File 'lib/brainstem/api_docs/endpoint.rb', line 122

def consumes
  @consumes ||= key_with_default_fallback(:consumes)
end

#contextual_documentation(key) ⇒ Object

Returns a key if it exists and is documentable



286
287
288
289
290
# File 'lib/brainstem/api_docs/endpoint.rb', line 286

def contextual_documentation(key)
  action_configuration.has_key?(key) &&
    !nodoc_for?(action_configuration[key]) &&
    action_configuration[key][:info]
end

#custom_responseObject



114
115
116
# File 'lib/brainstem/api_docs/endpoint.rb', line 114

def custom_response
  @custom_response ||= action_configuration[:custom_response]
end

#custom_response_configuration_treeHash{Symbol => Hash}

Returns a hash of all fields for a custom response nested under the specified parent fields along with their type, item type & children.

Returns:

  • (Hash{Symbol => Hash})

    root keys and their type info, item info & children nested under them.



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/brainstem/api_docs/endpoint.rb', line 190

def custom_response_configuration_tree
  return {} unless custom_response.present?

  @custom_response_configuration ||= begin
    custom_response_fields = custom_response
      .to_h
      .deep_dup
      .with_indifferent_access
    custom_config_tree = ActiveSupport::HashWithIndifferentAccess.new
    custom_config_tree[:_config] = custom_response_fields[:_config]

    custom_response_fields
      .except(:_config)
      .inject(custom_config_tree) do |result, (field_name_proc, field_config)|

      next result if nodoc_for?(field_config)
      field_config = field_config.except(:nodoc, :internal)

      field_name = evaluate_field_name(field_name_proc)
      if field_config.has_key?(:ancestors)
        ancestors = field_config[:ancestors].map { |ancestor_key| evaluate_field_name(ancestor_key) }

        parent = ancestors.inject(result) do |traversed_hash, ancestor_name|
          traversed_hash[ancestor_name] ||= { :_config => { type: 'hash' } }
          traversed_hash[ancestor_name]
        end

        parent[field_name] = { :_config => field_config.except(:ancestors) }
      else
        result[field_name] = { :_config => field_config }
      end

      result
    end
  end
end

#declared_presented_classObject

Used to retrieve this endpoint’s presenter constant.



248
249
250
251
252
# File 'lib/brainstem/api_docs/endpoint.rb', line 248

def declared_presented_class
  valid_presents.has_key?(:target_class) &&
    !nodoc_for?(valid_presents) &&
    valid_presents[:target_class]
end

#default_configurationObject

Retrieves default action context from the controller.



279
280
281
# File 'lib/brainstem/api_docs/endpoint.rb', line 279

def default_configuration
  configuration[:_default] || {}
end

#deprecatedObject



142
143
144
# File 'lib/brainstem/api_docs/endpoint.rb', line 142

def deprecated
  @deprecated ||= key_with_default_fallback(:deprecated)
end

#descriptionObject



106
107
108
# File 'lib/brainstem/api_docs/endpoint.rb', line 106

def description
  @description ||= contextual_documentation(:description) || ""
end

#evaluate_field_name(field_name_or_proc) ⇒ Object Also known as: evaluate_root_name

Evaluate field name if proc and symbolize it.



230
231
232
233
234
235
# File 'lib/brainstem/api_docs/endpoint.rb', line 230

def evaluate_field_name(field_name_or_proc)
  return field_name_or_proc if field_name_or_proc.nil?

  field_name = field_name_or_proc.respond_to?(:call) ? field_name_or_proc.call(controller.const) : field_name_or_proc
  field_name.to_sym
end

#external_docsObject



138
139
140
# File 'lib/brainstem/api_docs/endpoint.rb', line 138

def external_docs
  @external_docs ||= key_with_default_fallback(:external_docs)
end

#key_with_default_fallback(key) ⇒ Object



292
293
294
# File 'lib/brainstem/api_docs/endpoint.rb', line 292

def key_with_default_fallback(key)
  action_configuration[key] || default_configuration[key]
end

#merge_http_methods!(methods) ⇒ Object

Merges http methods (for de-duping Rails’ routes).



55
56
57
# File 'lib/brainstem/api_docs/endpoint.rb', line 55

def merge_http_methods!(methods)
  self.http_methods |= methods
end

#nodoc?Boolean

Is the entire endpoint undocumentable?

Returns:

  • (Boolean)


98
99
100
# File 'lib/brainstem/api_docs/endpoint.rb', line 98

def nodoc?
  nodoc_for?(action_configuration)
end

#operation_idObject



118
119
120
# File 'lib/brainstem/api_docs/endpoint.rb', line 118

def operation_id
  @operation_id ||= action_configuration[:operation_id]
end

#params_configuration_treeHash{Symbol => Hash}

Returns a hash of all params nested under the specified root or parent fields along with their type, item type & children.

Returns:

  • (Hash{Symbol => Hash})

    root keys and their type info, item info & children nested under them.



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/brainstem/api_docs/endpoint.rb', line 153

def params_configuration_tree
  @params_configuration_tree ||= begin
    valid_params
      .to_h
      .deep_dup
      .with_indifferent_access
      .inject(ActiveSupport::HashWithIndifferentAccess.new) do |result, (field_name_proc, field_config)|

      next result if nodoc_for?(field_config)
      field_config = field_config.except(:nodoc, :internal)

      field_name = evaluate_field_name(field_name_proc)
      if field_config.has_key?(:ancestors)
        ancestors = field_config[:ancestors].map { |ancestor_key| evaluate_field_name(ancestor_key) }

        parent = ancestors.inject(result) do |traversed_hash, ancestor_name|
          traversed_hash[ancestor_name] ||= { :_config => { type: 'hash' } }
          traversed_hash[ancestor_name]
        end

        parent[field_name] = { :_config => field_config.except(:root, :ancestors) }
      else
        result[field_name] = { :_config => field_config }
      end

      result
    end
  end
end

#presenter_titleObject



296
297
298
# File 'lib/brainstem/api_docs/endpoint.rb', line 296

def presenter_title
  presenter && presenter.title
end

#producesObject



126
127
128
# File 'lib/brainstem/api_docs/endpoint.rb', line 126

def produces
  @produces ||= key_with_default_fallback(:produces)
end

#relative_presenter_path_from_controller(format) ⇒ Object

Returns the relative path from this endpoint’s controller to this endpoint’s declared presenter.



304
305
306
307
308
309
310
311
# File 'lib/brainstem/api_docs/endpoint.rb', line 304

def relative_presenter_path_from_controller(format)
  if presenter && controller
    controller_path = Pathname.new(File.dirname(controller.suggested_filename_link(format)))
    presenter_path  = Pathname.new(presenter.suggested_filename_link(format))

    presenter_path.relative_path_from(controller_path).to_s
  end
end

#schemesObject



134
135
136
# File 'lib/brainstem/api_docs/endpoint.rb', line 134

def schemes
  @schemes ||= key_with_default_fallback(:schemes)
end

#securityObject



130
131
132
# File 'lib/brainstem/api_docs/endpoint.rb', line 130

def security
  @security ||= key_with_default_fallback(:security)
end

#titleObject



102
103
104
# File 'lib/brainstem/api_docs/endpoint.rb', line 102

def title
  @title ||= contextual_documentation(:title) || action.to_s.humanize
end

#to_sObject

Pretty prints each endpoint.



48
49
50
# File 'lib/brainstem/api_docs/endpoint.rb', line 48

def to_s
  "#{http_methods.join(" / ")} #{path}"
end

#valid_optionsObject



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/brainstem/api_docs/endpoint.rb', line 19

def valid_options
  super | [
    :path,
    :http_methods,
    :controller,
    :controller_name,
    :action,
    :presenter,
    :include_internal
  ]
end

#valid_paramsObject



110
111
112
# File 'lib/brainstem/api_docs/endpoint.rb', line 110

def valid_params
  @valid_params ||= key_with_default_fallback(:valid_params)
end

#valid_presentsObject

Retrieves the presents settings.



241
242
243
# File 'lib/brainstem/api_docs/endpoint.rb', line 241

def valid_presents
  key_with_default_fallback(:presents) || {}
end