Class: Watts::App
- Inherits:
-
Object
- Object
- Watts::App
- Defined in:
- lib/watts.rb
Overview
In order to have a Watts app, you’ll want to subclass Watts::App. For a good time, you’ll also probably want to provide some resources to that class using the resource method, which maps paths to resources.
Constant Summary collapse
- Errors =
{ 400 => [400, {'Content-Type' => 'text/plain'}, ["400 Bad Request.\n"]], 404 => [404, {'Content-Type' => 'text/plain'}, ["404 Not Found\n"]], 501 => [501, {'Content-Type' => 'text/plain'}, ["501 Not Implemented.\n"]], }
- ESet =
The “empty” set.
Set.new(['/', ''])
- MNCache =
Method name cache. Maps HTTP methods to object methods.
Hash.new { |h,k| h[k] = k.downcase.to_sym }
Class Attribute Summary collapse
-
.path_stack ⇒ Object
writeonly
Sets the attribute path_stack.
Class Method Summary collapse
- .decypher_path(p) ⇒ Object
-
.path_to(res, *args) ⇒ Object
Given a resource (and, optionally, arguments if the path requires them), this method returns an absolute path to the resource.
-
.resource(path, res = nil, &b) ⇒ Object
(also: res)
If you want your Watts application to do anything at all, you’re very likely to want to call this method at least once.
Instance Method Summary collapse
-
#call(env, req_path = nil) ⇒ Object
Our interaction with Rack.
-
#match(req_path) ⇒ Object
Given a path, returns the matching resource, if any.
Class Attribute Details
.path_stack=(value) ⇒ Object (writeonly)
Sets the attribute path_stack
94 95 96 |
# File 'lib/watts.rb', line 94 def path_stack=(value) @path_stack = value end |
Class Method Details
.decypher_path(p) ⇒ Object
97 98 99 100 101 102 |
# File 'lib/watts.rb', line 97 def self.decypher_path p return p if p.kind_of?(Array) return [] if ESet.include?(p) return [p] if p.kind_of?(Regexp) || p.kind_of?(Symbol) p.split('/').tap { |a| a.reject!(&''.method(:'==')) } end |
.path_to(res, *args) ⇒ Object
Given a resource (and, optionally, arguments if the path requires them), this method returns an absolute path to the resource.
159 160 161 |
# File 'lib/watts.rb', line 159 def self.path_to res, *args path_map.rmatch res, args end |
.resource(path, res = nil, &b) ⇒ Object Also known as: res
If you want your Watts application to do anything at all, you’re very likely to want to call this method at least once. The basic purpose of the method is to tell your app how to match a resource to a path. For example, if you create a resource (see Watts::Resource) Foo, and you want requests against ‘/foo’ to match it, you could do this: resource(‘foo’, Foo)
The first argument is the path, and the second is the resource that path is to match. (Please see the README for more detailed documentation of path-matching.) You may also pass it a block, in which resources that are defined are ‘namespaced’. For example, if you also had a resource called Bar and wanted its path to be a sub-path of the Foo resource’s (e.g., ‘/foo/bar’), then typing these lines is a pretty good plan: resource(‘foo’, Foo) { resource(‘bar’, Bar) }
Lastly, the resource argument itself is optional, for when you want a set of resources to be namespaced under a given path, but don’t have a resource in mind. For example, if you suddenly needed your entire application to reside under ‘/api’, you could do this: resource(‘api’) {
resource('foo', Foo) {
resource(‘bar’, Bar) resource(‘baz’, Baz) } }
This is probably the most important method in Watts. Have a look at the README and the example applications under doc/examples if you want to understand the pattern-matching, arguments to resources, etc.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/watts.rb', line 138 def self.resource(path, res = nil, &b) path = decypher_path(path) last = (path_stack + path).inject(path_map) { |m,p| m[p] ||= Path.new } last.resource = res if b old_stack = path_stack self.path_stack = old_stack + path b.call self.path_stack = old_stack end res end |
Instance Method Details
#call(env, req_path = nil) ⇒ Object
Our interaction with Rack.
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/watts.rb', line 170 def call env, req_path = nil rm = MNCache[env['REQUEST_METHOD']] return(Errors[501]) unless Resource::HTTPMethods.include?(rm) req_path ||= decypher_path env['PATH_INFO'] resource_class, args = path_map.match req_path, [] if resource_class env[:watts_app] ||= self res = resource_class.new env res.send(rm, *args) else Errors[404] end end |
#match(req_path) ⇒ Object
Given a path, returns the matching resource, if any.
164 165 166 167 |
# File 'lib/watts.rb', line 164 def match req_path req_path = decypher_path req_path path_map.match req_path, [] end |