Class: Praxis::Router

Inherits:
Object
  • Object
show all
Defined in:
lib/praxis/router.rb

Defined Under Namespace

Classes: RequestRouter, VersionMatcher

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(application, request_class: Praxis::Request) ⇒ Router

Returns a new instance of Router.



44
45
46
47
48
49
50
# File 'lib/praxis/router.rb', line 44

def initialize(application, request_class: Praxis::Request)
  @routes = Hash.new do |hash, verb|
    hash[verb] = RequestRouter.new
  end
  @request_class = request_class
  @application = application
end

Instance Attribute Details

#applicationObject (readonly)

Returns the value of attribute application.



7
8
9
# File 'lib/praxis/router.rb', line 7

def application
  @application
end

#request_classObject (readonly)

Returns the value of attribute request_class.



6
7
8
# File 'lib/praxis/router.rb', line 6

def request_class
  @request_class
end

Instance Method Details

#add_route(target, route) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/praxis/router.rb', line 52

def add_route(target, route)
  path_versioning = (Application.instance.versioning_scheme == :path)

  # DEPRECATED: remove with ResourceDefinition.version using: :path
  path_versioning ||= (target.action.resource_definition.version_options[:using] == :path)

  unless path_versioning
    target = VersionMatcher.new(target, version: route.version)
  end

  @routes[route.verb].on(route.path, call: target)
end

#call(env_or_request) ⇒ Object



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
# File 'lib/praxis/router.rb', line 65

def call(env_or_request)
  request = case env_or_request
  when Hash
    request_class.new(env_or_request)
  when request_class
    env_or_request
  else
    raise ArgumentError, "received #{env_or_request.class}"
  end

  verb = request.verb
  r = ( @routes.key?(verb) ? @routes[verb] : nil )  # Exact verb match
  result = r.call(request) if r
  # If we didn't have an exact verb route, or if we did but the rest or route conditions didn't match
  if( r == nil || result == :not_found )
    # Fallback to a wildcard router, if there is one registered
    result = if @routes.key?('ANY')
      @routes['ANY'].call(request)
    else
      :not_found
    end
  end

  if result == :not_found
    # no need to try :path as we cannot really know if you've attempted to pass a version through it here
    # plus we wouldn't have tracked it as unmatched
    version = request.version
    attempted_versions = request.unmatched_versions
    body = "NotFound"
    unless attempted_versions.empty? || (attempted_versions.size == 1 && attempted_versions.first == 'n/a')
      body += if version == 'n/a'
        ". Your request did not specify an API version.".freeze
      else
        ". Your request specified API version = \"#{version}\"."
      end
      pretty_versions = attempted_versions.collect(&:inspect).join(', ')
      body += " Available versions = #{pretty_versions}."
    end
    headers = {"Content-Type" => "text/plain"}
    if Praxis::Application.instance.config.praxis.x_cascade
      headers['X-Cascade'] = 'pass'
    end
    result = [404, headers, [body]]
  end
  result
end