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.



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

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.



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

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



50
51
52
53
# File 'lib/praxis/router.rb', line 50

def add_route(target, route)
  version_wrapper = VersionMatcher.new(target, version: route.version)
  @routes[route.verb].on(route.path, call: version_wrapper)
end

#call(env_or_request) ⇒ Object



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
91
92
93
94
95
96
97
98
99
100
# File 'lib/praxis/router.rb', line 55

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(using: [:header,:params])
    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 speficied 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