restrack 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,282 @@
1
+ <h1>RESTRack</h1>
2
+
3
+ <ul>
4
+ <li>serving JSON and XML with REST and pleasure.</li>
5
+ </ul>
6
+
7
+ <h2>Description:</h2>
8
+
9
+ <p>RESTRack is a <a href="http://rack.rubyforge.org/">Rack</a>-based <a href="http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller">MVC</a>
10
+ framework that makes it extremely easy to develop <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a>ful
11
+ data services. It is inspired by Rails, and follows a few of its conventions. But it has no routes file, routing
12
+ relationships are done through supplying custom code blocks to class methods such as "has_relationship_to" or
13
+ "has_mapped_relationships_to".</p>
14
+
15
+ <p>RESTRack aims at being lightweight and easy to use. It will automatically render JSON and XML for the data
16
+ structures you return in your actions (any structure parsable by the "<a href="http://flori.github.com/json/">json</a>" and
17
+ "<a href="https://github.com/maik/xml-simple">xml-simple</a>" gems, respectively).</p>
18
+
19
+ <p>If you supply a view for a controller action, you do that using a builder file. Builder files are stored in the
20
+ view directory grouped by controller name subdirectories (<code>view/&lt;controller&gt;/&lt;action&gt;.xml.builder</code>). XML format
21
+ requests will then render the view template with the builder gem, rather than generating XML with XmlSimple.</p>
22
+
23
+ <h2>Installation:</h2>
24
+
25
+ <h3>Using <a href="http://rubygems.org">RubyGems</a>:</h3>
26
+
27
+ <pre><code>&lt;sudo&gt; gem install restrack
28
+ </code></pre>
29
+
30
+ <h2>Why RESTRack when there is Rails?</h2>
31
+
32
+ <p><a href="http://rubyonrails.org/">Rails</a> is a powerful tool for full web applications. RESTRack is targeted at making
33
+ development of lightweight data services as easy as possible, while still giving you a performant and extensible
34
+ framework. The primary goal of of the development of RESTRack was to add as little as possible to the framework to give
35
+ the web developer a good application space for developing JSON and XML services.</p>
36
+
37
+ <p>Rails 3 instantiates approximately 80K more objects than RESTRack to do a hello world or nothing type response with
38
+ the default setup. Trimming Rails down by eliminating ActiveRecord, ActionMailer, and ActiveResource, it still
39
+ instantiates over 47K more objects than RESTRack.</p>
40
+
41
+ <h2>CLI Usage:</h2>
42
+
43
+ <h3>Generate a new service (FooBar::WebService)</h3>
44
+
45
+ <ul>
46
+ <li>restrack generate service foo_bar</li>
47
+ <li>restrack gen serv foo_bar</li>
48
+ <li>restrack g s foo_bar</li>
49
+ </ul>
50
+
51
+ <h3>Generate a new controller (FooBar::BazController)</h3>
52
+
53
+ <ul>
54
+ <li>restrack generate controller baz</li>
55
+ <li>restrack gen cont baz</li>
56
+ <li>restrack g c baz</li>
57
+ </ul>
58
+
59
+ <h3>Generate a new controller that descends from another (FooBar::NewController &lt; FooBar::BazController)</h3>
60
+
61
+ <ul>
62
+ <li>restrack generate controller new descendant_from baz</li>
63
+ <li>restrack g controller new parent baz</li>
64
+ </ul>
65
+
66
+ <h3>Start up a server on default rackup port 9292</h3>
67
+
68
+ <ul>
69
+ <li>restrack server</li>
70
+ </ul>
71
+
72
+ <h3>Start up a server on port 3456</h3>
73
+
74
+ <ul>
75
+ <li>restrack server 3456</li>
76
+ <li>restrack s 3456</li>
77
+ </ul>
78
+
79
+ <h2>REST action method names</h2>
80
+
81
+ <p>All default RESTful controller method names align with their Rails counterparts, with two additional actions being
82
+ supported(*).</p>
83
+
84
+ <pre><code> HTTP Verb: | GET | PUT | POST | DELETE
85
+ Collection URI (/widgets/): | index | replace | create | *drop
86
+ Element URI (/widgets/42): | show | update | *add | destroy
87
+ </code></pre>
88
+
89
+ <h2>URLs and Controller relationships</h2>
90
+
91
+ <p>RESTRack enforces a strict URL pattern through the contruct of controller relationships, rather than a routing file.
92
+ Defining a controller for a resource means that you plan to expose that resource to requests to your service.
93
+ Defining a controller relationship means that you plan to expose a path from this resource to another.</p>
94
+
95
+ <h3>"pass_through_to"</h3>
96
+
97
+ <p>An open, or pass-through, path can be defined via the "pass_through_to" class method for resource controllers. This
98
+ exposes URL patterns like the following:</p>
99
+
100
+ <pre><code>GET /foo/123/bar/234 &lt;= simple pass-through from Foo 123 to show Bar 234
101
+ GET /foo/123/bar &lt;= simple pass-through from Foo 123 to Bar index
102
+ </code></pre>
103
+
104
+ <h3>"has_relationship_to"</h3>
105
+
106
+ <p>A direct path to a single related resource's controller can be defined with the "has_relationship_to" method. This
107
+ allows you to define a one-to-one relationship from this resource to a related resource, which means that the id of
108
+ the related resource is implied through the id of the caller. The caller has one relation through a custom code block
109
+ passed to "has_relationship_to". The code block takes the caller resource's id and evaluates to the relation
110
+ resource's id, for example a PeopleController might define a one-to-one relationship like so:</p>
111
+
112
+ <pre><code> has_relationship_to( :people, :as spouse ) do |id|
113
+ People.find(id).spouse.id
114
+ end
115
+ </code></pre>
116
+
117
+ <p>This exposes URL patterns like the following:</p>
118
+
119
+ <pre><code>GET /people/Sally/spouse &lt;= direct route to show Sally's spouse
120
+ PUT /people/Henry/spouse &lt;= direct route to update Henry's spouse
121
+ POST /people/Jane/spouse &lt;= direct route to add Jane's spouse
122
+ </code></pre>
123
+
124
+ <h3>"has_relationships_to" and "has_defined_relationships_to"</h3>
125
+
126
+ <p>A direct path to many related resources' controller can be defined with the "has_relationships_to" and
127
+ "has_defined_relationships_to" methods. These allows you to define one-to-many relationships. They work similar to
128
+ "has_relationship_to", except that they accept code blocks which evaluate to arrays of related child ids. Each
129
+ resource in the parent's relation list is then accessed through its array index (zero-based) in the URL. An example
130
+ of exposing the list of a People resource's children in this manner follows:</p>
131
+
132
+ <pre><code> has_relationships_to( :people, :as =&gt; children ) do |id|
133
+ People.find(id).children.collect {|child| child.id}
134
+ end
135
+ </code></pre>
136
+
137
+ <p>Which exposes URLs similar to:</p>
138
+
139
+ <pre><code>GET /people/Nancy/children/0 &lt;= direct route to show child 0
140
+ DELETE /people/Robert/children/100 &lt;= direct route to destroy child 100
141
+ </code></pre>
142
+
143
+ <p>An example of "has_defined_relationships_to":</p>
144
+
145
+ <pre><code> has_defined_relationships_to( :people, :as =&gt; children ) do |id|
146
+ People.find(id).children.collect {|child| child.id}
147
+ end
148
+ </code></pre>
149
+
150
+ <p>exposes URL patterns:</p>
151
+
152
+ <pre><code>GET /people/Nancy/children/George &lt;= route to show child George
153
+ DELETE /people/Robert/children/Jerry &lt;= route to destroy child Jerry
154
+ </code></pre>
155
+
156
+ <h3>"has_mapped_relationships_to"</h3>
157
+
158
+ <p>Multiple named one-to-many relationships can be exposed with the "has_mapped_relationships_to" method. This allows
159
+ you to define many named or keyword paths to related resources. The method's code block should accepts the parent id
160
+ and return a hash where the keys are your relationship names and the values are the child resource ids. For example,
161
+ within a PeopleController the following definition:</p>
162
+
163
+ <pre><code> has_mapped_relationships_to( :people ) do |id|
164
+ {
165
+ 'father' =&gt; People.find(id).father.id,
166
+ 'mother' =&gt; People.find(id).mother.id,
167
+ 'boss' =&gt; People.find(id).boss.id,
168
+ 'assistant' =&gt; People.find(id).assistant.id
169
+ }
170
+ end
171
+ </code></pre>
172
+
173
+ <p>This would expose the following URL patterns:</p>
174
+
175
+ <pre><code>GET /people/Fred/people/father =&gt; show the father of Fred
176
+ PUT /people/Fred/people/assistant =&gt; update Fred's assistant
177
+ POST /people/Fred/people/boss =&gt; add Fred's boss
178
+ DELETE /people/Luke/people/mother =&gt; destroy Luke's father
179
+ </code></pre>
180
+
181
+ <h3>Setting the data type of the id - "keyed_with_type"</h3>
182
+
183
+ <p>Resource id data types can be defined with the "keyed_with_type" class method within resource controllers. The
184
+ default data type of String is used if a different type is not specified.</p>
185
+
186
+ <h2>Logging/Logging Level</h2>
187
+
188
+ <p>RESTRack outputs to two logs, the standard log (or error log) and the request log. Paths and logging levels for these
189
+ can be configured in <code>config/constants.yaml</code>. RESTRack uses Logger from Ruby-stdlib.</p>
190
+
191
+ <h2>XML Serialization</h2>
192
+
193
+ <p>RESTRack will convert the data structures that your actions return to JSON by default. You can change the default
194
+ by setting :DEFAULT_FORMAT to :XML in <code>config/constants.yml</code>.</p>
195
+
196
+ <h3>With XmlSimple</h3>
197
+
198
+ <p>RESTRack will attempt to serialize the data structures that your action methods return automatically using the
199
+ xml-simple gem.</p>
200
+
201
+ <h3>With Builder</h3>
202
+
203
+ <p>Custom XML serialization can be done by providing Builder gem templates in <code>views/&lt;controller&gt;/&lt;action&gt;.xml.builder</code>.</p>
204
+
205
+ <h2>Inputs</h2>
206
+
207
+ <h3>Query string parameters</h3>
208
+
209
+ <p>Available to controllers in the <code>@params</code> instance variable.</p>
210
+
211
+ <h3>POST data</h3>
212
+
213
+ <p>Available to controllers in the <code>@input</code> instance variable.</p>
214
+
215
+ <h2>Constant Definition (<code>config/constants.yaml</code>)</h2>
216
+
217
+ <h3>Required Configuration Settings</h3>
218
+
219
+ <h4>:LOG</h4>
220
+
221
+ <p>Sets the location of the error log.</p>
222
+
223
+ <h4>:REQUEST_LOG</h4>
224
+
225
+ <p>Sets the location of the request log.</p>
226
+
227
+ <h4>:LOG_LEVEL</h4>
228
+
229
+ <p>Sets the the logging level of the error log, based on the Ruby Logger object. Supply these as a symbol, with valid
230
+ values being :DEBUG, :INFO, :WARN, etc.</p>
231
+
232
+ <h4>:REQUEST_LOG_LEVEL</h4>
233
+
234
+ <p>Sets the the logging level of the request log, similar to :LOG_LEVEL.</p>
235
+
236
+ <h3>Optional Configuration Settings</h3>
237
+
238
+ <h4>:DEFAULT_FORMAT</h4>
239
+
240
+ <p>Sets the default format for the response. This is the format that the response will take if no extension is appended to
241
+ the request string (i.e. <code>/foo/123</code> rather than <code>/foo/123.xml</code>). Services will have a default format of JSON if this
242
+ configuration option is not defined.</p>
243
+
244
+ <h4>:DEFAULT_RESOURCE</h4>
245
+
246
+ <p>Set this option in config/constants.yaml to use an implied root resource controller. To make <code>/foo/123</code> also be accessible
247
+ at <code>/123</code>:</p>
248
+
249
+ <pre><code>:DEFAULT_RESOURCE: foo
250
+ </code></pre>
251
+
252
+ <h4>:ROOT_RESOURCE_ACCEPT</h4>
253
+
254
+ <p>This defines an array of resources that can be accessed as the first resource in the URL chain, without being proxied
255
+ through another relation.</p>
256
+
257
+ <pre><code>:ROOT_RESOURCE_ACCEPT: [ 'foo', 'bar' ]
258
+ </code></pre>
259
+
260
+ <h4>:ROOT_RESOURCE_DENY</h4>
261
+
262
+ <p>This defines an array of resources that cannot be accessed without proxying though another controller.</p>
263
+
264
+ <pre><code>:ROOT_RESOURCE_DENY: [ 'baz' ]
265
+ </code></pre>
266
+
267
+ <h2>License</h2>
268
+
269
+ <p>Copyright (c) 2010 Chris St. John</p>
270
+
271
+ <p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
272
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
273
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
274
+ persons to whom the Software is furnished to do so, subject to the following conditions:</p>
275
+
276
+ <p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
277
+ Software.</p>
278
+
279
+ <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
280
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
281
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
282
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p>
@@ -1,3 +1,3 @@
1
1
  module RESTRack
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -1,8 +1,5 @@
1
1
  module RESTRack
2
2
  class WebService
3
- # TODO: Fix logging, routes duplicated
4
- # TODO: only one "info" level log for 200 to request log or one "warn" for <500 or "error" for 500, all else goes to error log
5
- # request log data should contain status code, request IP address, request path, request_id
6
3
 
7
4
  # Establish the namespace pointer.
8
5
  def initialize
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- Komodo Project File - DO NOT EDIT -->
3
+ <project id="1b07bef2-e0ab-1142-afc9-806da10889c5" kpf_version="5" name="restrack.komodoproject">
4
+ <preference-set idref="1b07bef2-e0ab-1142-afc9-806da10889c5">
5
+ <boolean id="import_live">1</boolean>
6
+ </preference-set>
7
+ </project>
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: restrack
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.1.0
5
+ version: 1.1.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Chris St. John
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-07-10 00:00:00 -04:00
13
+ date: 2011-07-17 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -122,6 +122,7 @@ extra_rdoc_files: []
122
122
  files:
123
123
  - Gemfile
124
124
  - README.markdown
125
+ - README.markdown.html
125
126
  - Rakefile
126
127
  - bin/restrack
127
128
  - lib/restrack.rb
@@ -138,6 +139,7 @@ files:
138
139
  - lib/restrack/version.rb
139
140
  - lib/restrack/web_service.rb
140
141
  - restrack.gemspec
142
+ - restrack.komodoproject
141
143
  - test/sample_app_1/config.ru
142
144
  - test/sample_app_1/config/constants.yaml
143
145
  - test/sample_app_1/controllers/bat_controller.rb