Class: Modern::Descriptor::Route

Inherits:
Struct
  • Object
show all
Defined in:
lib/modern/descriptor/route.rb

Constant Summary collapse

TEMPLATE_TOKEN =

TODO: define OpenAPI-style callbacks

%r|\{.+\}|
OPENAPI_CAPTURE =
%r|/\{(?<name>.+?)\}|

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Struct::Copy

#copy

Constructor Details

#initialize(fields) ⇒ Route

Returns a new instance of Route.



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
# File 'lib/modern/descriptor/route.rb', line 52

def initialize(fields)
  super

  @path_matcher = Regexp.new("^" + path.gsub(OPENAPI_CAPTURE, "/(?<\\k<name>>[^/]+)") + "$")
  @route_tokens =
    path.sub(%r|^/|, "").split("/").map do |token|
      TEMPLATE_TOKEN =~ token ? :templated : token
    end

  @content_types = responses.map { |r| r.content.map(&:media_type) }.flatten.to_set.freeze
  @responses_by_code = responses.map { |r| [r.http_code, r] }.to_h.freeze

  raise "Cannot create a Route without a Response where http_code = :default." \
    unless @responses_by_code.key?(:default)

  _nondefault_content = @content_types - @responses_by_code[:default].content.map(&:media_type).to_set
  # TODO: figure out how to better validate these
  #       This might be a larger-scale problem. The DSL creates a route with this, and you can end
  #       up in a case where you try to add a new content type to another response type. This causes
  #       the commented test below to fail unless you defined the :default response, with that content
  #       type, higher in the DSL. We might need some sort of intermediate builder class, or a way to
  #       squelch this error somehow...
  # require 'pry'; binding.pry
  # raise "Missing content types in default HTTP response for #{id}: #{nondefault_content.to_a.join(', ')}" \
  #     unless nondefault_content.empty?

  @input_converters_by_type = input_converters.map { |c| [c.media_type.downcase.strip, c] }.to_h.freeze
  @output_converters_by_type = output_converters.map { |c| [c.media_type.downcase.strip, c] }.to_h.freeze

  @request_container_class =
    if helpers.empty?
      Modern::App::RequestHandling::FullRequestContainer
    else
      rcc = Class.new(Modern::App::RequestHandling::FullRequestContainer)
      helpers.each { |h| rcc.send(:include, h) }

      rcc
    end
end

Instance Attribute Details

#content_typesObject (readonly)

Returns the value of attribute content_types.



44
45
46
# File 'lib/modern/descriptor/route.rb', line 44

def content_types
  @content_types
end

#input_converters_by_typeObject (readonly)

Returns the value of attribute input_converters_by_type.



47
48
49
# File 'lib/modern/descriptor/route.rb', line 47

def input_converters_by_type
  @input_converters_by_type
end

#output_converters_by_typeObject (readonly)

Returns the value of attribute output_converters_by_type.



48
49
50
# File 'lib/modern/descriptor/route.rb', line 48

def output_converters_by_type
  @output_converters_by_type
end

#path_matcherObject (readonly)

Returns the value of attribute path_matcher.



41
42
43
# File 'lib/modern/descriptor/route.rb', line 41

def path_matcher
  @path_matcher
end

#request_container_classObject (readonly)

Returns the value of attribute request_container_class.



50
51
52
# File 'lib/modern/descriptor/route.rb', line 50

def request_container_class
  @request_container_class
end

#responses_by_codeObject (readonly)

Returns the value of attribute responses_by_code.



45
46
47
# File 'lib/modern/descriptor/route.rb', line 45

def responses_by_code
  @responses_by_code
end

#route_tokensObject (readonly)

Returns the value of attribute route_tokens.



42
43
44
# File 'lib/modern/descriptor/route.rb', line 42

def route_tokens
  @route_tokens
end