restrack 1.3.4 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -4,13 +4,13 @@
4
4
  ## Description:
5
5
  RESTRack is a [Rack](http://rack.rubyforge.org/)-based [MVC](http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller)
6
6
  framework that makes it extremely easy to develop [REST](http://en.wikipedia.org/wiki/Representational_State_Transfer)ful
7
- data services. It is inspired by Rails, and follows a few of its conventions. But it has no routes file, routing
8
- relationships are done through supplying custom code blocks to class methods such as "has\_relationship\_to" or
7
+ data services. It is inspired by [Rails](http://rubyonrails.org), and follows a few of its conventions. But it has no routes
8
+ file, routing relationships are done through supplying custom code blocks to class methods such as "has\_relationship\_to" or
9
9
  "has\_mapped\_relationships\_to".
10
10
 
11
- RESTRack aims at being lightweight and easy to use. It will automatically render JSON and XML for the data
12
- structures you return in your actions \(any structure parsable by the "[json](http://flori.github.com/json/)" and
13
- "[xml-simple](https://github.com/maik/xml-simple)" gems, respectively\).
11
+ RESTRack aims at being lightweight and easy to use. It will automatically render [JSON](http://www.json.org/) and
12
+ [XML](http://www.w3.org/XML/) for the data structures you return in your actions \(any structure parsable by the
13
+ "[json](http://flori.github.com/json/)" and "[xml-simple](https://github.com/maik/xml-simple)" gems, respectively\).
14
14
 
15
15
  If you supply a view for a controller action, you do that using a builder file. Builder files are stored in the
16
16
  view directory grouped by controller name subdirectories \(`view/<controller>/<action>.xml.builder`\). XML format
@@ -32,6 +32,9 @@ Rails 3 instantiates approximately 80K more objects than RESTRack to do a hello
32
32
  the default setup. Trimming Rails down by eliminating ActiveRecord, ActionMailer, and ActiveResource, it still
33
33
  instantiates over 47K more objects than RESTRack.
34
34
 
35
+ ## OK, so why RESTRack when there is Sinatra?
36
+ RESTRack provides a full, albeit small, framework for developing RESTful MVC applications.
37
+
35
38
 
36
39
  ## CLI Usage:
37
40
  ### Generate a new service \(FooBar::WebService\)
@@ -65,6 +68,65 @@ supported\(\*\).
65
68
  Element URI (/widgets/42): | show | update | *add | destroy
66
69
 
67
70
 
71
+ ## Automatic response data serialization
72
+ ### JSON
73
+ Objects returned from resource controller methods will have the "to\_json" method called to serialize response output.
74
+ Controllers should return objects that respond to "to\_json". RESTRack includes the JSON gem, which implements this method
75
+ on Ruby's standard lib simple data types (Array, Hash, String etc).
76
+
77
+ # GET /widgets/42.json
78
+ def show(id) # id will be 42
79
+ widget = Widget.find(id)
80
+ return widget
81
+ # The widget.to_json will be called and the resultant JSON sent as response body.
82
+ end
83
+
84
+ # GET /widgets/42
85
+ def show(id) # id will be 42
86
+ widget = Widget.find(id)
87
+ return widget
88
+ # The widget.to_json will be called unless the default response type is set to :XML in config/constants.yaml,
89
+ # in which case the widget.to_xml method will be called.
90
+ end
91
+
92
+ ### XML
93
+ RESTRack will convert the data structures that your actions return to JSON by default. You can change the default
94
+ by setting :DEFAULT_FORMAT to :XML in `config/constants.yml`.
95
+
96
+ #### With Builder
97
+ Custom XML serialization can be done by providing [Builder](http://builder.rubyforge.org/) gem templates in `views/<controller>/<action>.xml.builder`.
98
+
99
+ #### Custom Serialization Method
100
+ When XML is requested, objects returned from resource controller methods will have the "to_xml" method called to serialize
101
+ response output if an XML builder template file is not provided. If the response object does not respond to "to_xml", then
102
+ the object will be sent to XmlSimple for serialization.
103
+
104
+ #### With XmlSimple
105
+ RESTRack will attempt to serialize the data structures that your action methods return automatically using the
106
+ xml-simple gem. Complex objects may not serialize correctly, or you may want to define a particular structure for your
107
+ XML, in which case a builder template should be defined.
108
+
109
+ # GET /widgets/42.xml
110
+ def show(id) # id will be 42
111
+ widget = Widget.find(id)
112
+ return widget
113
+ # Template file views/widgets/show.xml.builder will be used to render the XML if it exists.
114
+ # If not, the widget.to_xml method will be called and the resultant XML sent as response body,
115
+ # or, if widget does not respond to "to_xml", then XmlSimple will be used to serialize the data object.
116
+ end
117
+
118
+
119
+ ## Accepting parameters and generating a response
120
+ Input parameters are accessible through the @params object. This is a merged hash containing the POST and GET parameters,
121
+ which can be accessed separately through @post_params and @get_params.
122
+
123
+ # GET /widgets/list.xml?offset=100&limit=50
124
+ def list
125
+ widget_list = Widget.limit( @params['limit'], @params['offset'] )
126
+ return widget_list
127
+ end
128
+
129
+
68
130
  ## URLs and Controller relationships
69
131
  RESTRack enforces a strict URL pattern through the contruct of controller relationships, rather than a routing file.
70
132
  Defining a controller for a resource means that you plan to expose that resource to requests to your service.
@@ -152,18 +214,6 @@ default data type of String is used if a different type is not specified.
152
214
  RESTRack outputs to two logs, the standard log (or error log) and the request log. Paths and logging levels for these
153
215
  can be configured in `config/constants.yaml`. RESTRack uses Logger from Ruby-stdlib.
154
216
 
155
- ## XML Serialization
156
- RESTRack will convert the data structures that your actions return to JSON by default. You can change the default
157
- by setting :DEFAULT_FORMAT to :XML in `config/constants.yml`.
158
-
159
- ### With XmlSimple
160
- RESTRack will attempt to serialize the data structures that your action methods return automatically using the
161
- xml-simple gem. Complex objects may not serialize correctly, or you may want to define a particular structure for your
162
- XML, in which case a builder template should be defined (see next heading).
163
-
164
- ### With Builder
165
- Custom XML serialization can be done by providing [Builder](http://builder.rubyforge.org/) gem templates in `views/<controller>/<action>.xml.builder`.
166
-
167
217
 
168
218
  ## Inputs
169
219
 
@@ -216,6 +266,13 @@ This defines an array of resources that cannot be accessed without proxying thou
216
266
  :ROOT_RESOURCE_DENY: [ 'baz' ]
217
267
 
218
268
 
269
+ #### :SHOW\_STACK
270
+ If defined, server error messages will contain the stack trace. This is not recommended when these errors could possibly
271
+ be delivered to the client.
272
+
273
+ :SHOW_STACK: true
274
+
275
+
219
276
  ## License
220
277
 
221
278
  Copyright (c) 2010 Chris St. John
data/README.markdown.html CHANGED
@@ -8,13 +8,13 @@
8
8
 
9
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
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
11
+ data services. It is inspired by <a href="http://rubyonrails.org">Rails</a>, and follows a few of its conventions. But it has no routes
12
+ file, routing relationships are done through supplying custom code blocks to class methods such as "has_relationship_to" or
13
13
  "has_mapped_relationships_to".</p>
14
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>
15
+ <p>RESTRack aims at being lightweight and easy to use. It will automatically render <a href="http://www.json.org/">JSON</a> and
16
+ <a href="http://www.w3.org/XML/">XML</a> for the data structures you return in your actions (any structure parsable by the
17
+ "<a href="http://flori.github.com/json/">json</a>" and "<a href="https://github.com/maik/xml-simple">xml-simple</a>" gems, respectively).</p>
18
18
 
19
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
20
  view directory grouped by controller name subdirectories (<code>view/&lt;controller&gt;/&lt;action&gt;.xml.builder</code>). XML format
@@ -38,6 +38,10 @@ the web developer a good application space for developing JSON and XML services.
38
38
  the default setup. Trimming Rails down by eliminating ActiveRecord, ActionMailer, and ActiveResource, it still
39
39
  instantiates over 47K more objects than RESTRack.</p>
40
40
 
41
+ <h2>OK, so why RESTRack when there is Sinatra?</h2>
42
+
43
+ <p>RESTRack provides a full, albeit small, framework for developing RESTful MVC applications.</p>
44
+
41
45
  <h2>CLI Usage:</h2>
42
46
 
43
47
  <h3>Generate a new service (FooBar::WebService)</h3>
@@ -86,6 +90,73 @@ supported(*).</p>
86
90
  Element URI (/widgets/42): | show | update | *add | destroy
87
91
  </code></pre>
88
92
 
93
+ <h2>Automatic response data serialization</h2>
94
+
95
+ <h3>JSON</h3>
96
+
97
+ <p>Objects returned from resource controller methods will have the "to_json" method called to serialize response output.
98
+ Controllers should return objects that respond to "to_json". RESTRack includes the JSON gem, which implements this method
99
+ on Ruby's standard lib simple data types (Array, Hash, String etc).</p>
100
+
101
+ <pre><code># GET /widgets/42.json
102
+ def show(id) # id will be 42
103
+ widget = Widget.find(id)
104
+ return widget
105
+ # The widget.to_json will be called and the resultant JSON sent as response body.
106
+ end
107
+
108
+ # GET /widgets/42
109
+ def show(id) # id will be 42
110
+ widget = Widget.find(id)
111
+ return widget
112
+ # The widget.to_json will be called unless the default response type is set to :XML in config/constants.yaml,
113
+ # in which case the widget.to_xml method will be called.
114
+ end
115
+ </code></pre>
116
+
117
+ <h3>XML</h3>
118
+
119
+ <p>RESTRack will convert the data structures that your actions return to JSON by default. You can change the default
120
+ by setting :DEFAULT_FORMAT to :XML in <code>config/constants.yml</code>.</p>
121
+
122
+ <h4>With Builder</h4>
123
+
124
+ <p>Custom XML serialization can be done by providing <a href="http://builder.rubyforge.org/">Builder</a> gem templates in <code>views/&lt;controller&gt;/&lt;action&gt;.xml.builder</code>.</p>
125
+
126
+ <h4>Custom Serialization Method</h4>
127
+
128
+ <p>When XML is requested, objects returned from resource controller methods will have the "to<em>xml" method called to serialize
129
+ response output if an XML builder template file is not provided. If the response object does not respond to "to</em>xml", then
130
+ the object will be sent to XmlSimple for serialization.</p>
131
+
132
+ <h4>With XmlSimple</h4>
133
+
134
+ <p>RESTRack will attempt to serialize the data structures that your action methods return automatically using the
135
+ xml-simple gem. Complex objects may not serialize correctly, or you may want to define a particular structure for your
136
+ XML, in which case a builder template should be defined.</p>
137
+
138
+ <pre><code># GET /widgets/42.xml
139
+ def show(id) # id will be 42
140
+ widget = Widget.find(id)
141
+ return widget
142
+ # Template file views/widgets/show.xml.builder will be used to render the XML if it exists.
143
+ # If not, the widget.to_xml method will be called and the resultant XML sent as response body,
144
+ # or, if widget does not respond to "to_xml", then XmlSimple will be used to serialize the data object.
145
+ end
146
+ </code></pre>
147
+
148
+ <h2>Accepting parameters and generating a response</h2>
149
+
150
+ <p>Input parameters are accessible through the @params object. This is a merged hash containing the POST and GET parameters,
151
+ which can be accessed separately through @post<em>params and @get</em>params.</p>
152
+
153
+ <pre><code># GET /widgets/list.xml?offset=100&amp;limit=50
154
+ def list
155
+ widget_list = Widget.limit( @params['limit'], @params['offset'] )
156
+ return widget_list
157
+ end
158
+ </code></pre>
159
+
89
160
  <h2>URLs and Controller relationships</h2>
90
161
 
91
162
  <p>RESTRack enforces a strict URL pattern through the contruct of controller relationships, rather than a routing file.
@@ -188,20 +259,6 @@ default data type of String is used if a different type is not specified.</p>
188
259
  <p>RESTRack outputs to two logs, the standard log (or error log) and the request log. Paths and logging levels for these
189
260
  can be configured in <code>config/constants.yaml</code>. RESTRack uses Logger from Ruby-stdlib.</p>
190
261
 
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
262
  <h2>Inputs</h2>
206
263
 
207
264
  <h3>Query string parameters</h3>
@@ -264,6 +321,14 @@ through another relation.</p>
264
321
  <pre><code>:ROOT_RESOURCE_DENY: [ 'baz' ]
265
322
  </code></pre>
266
323
 
324
+ <h4>:SHOW_STACK</h4>
325
+
326
+ <p>If defined, server error messages will contain the stack trace. This is not recommended when these errors could possibly
327
+ be delivered to the client.</p>
328
+
329
+ <pre><code>:SHOW_STACK: true
330
+ </code></pre>
331
+
267
332
  <h2>License</h2>
268
333
 
269
334
  <p>Copyright (c) 2010 Chris St. John</p>
@@ -1,3 +1,3 @@
1
1
  module RESTRack
2
- VERSION = "1.3.4"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -60,8 +60,12 @@ module RESTRack
60
60
  else
61
61
  RESTRack.log.error "(<nil-reqid>) #{exception.class.to_s} " + exception.message + "\n" + exception.backtrace.join("\n")
62
62
  end
63
- # TODO: Make it configurable whether or not exception includes stack trace
64
- msg = (exception.message == exception.class.to_s) ? exception.backtrace.join("\n") : exception.message + "\nstack trace:\n" + exception.backtrace.join("\n")
63
+ msg = ''
64
+ if RESTRack::CONFIG[:SHOW_STACK]
65
+ msg = (exception.message == exception.class.to_s) ? exception.backtrace.join("\n") : exception.message + "\nstack trace:\n" + exception.backtrace.join("\n")
66
+ else
67
+ msg = exception.message
68
+ end
65
69
  return [500, {'Content-Type' => 'text/plain'}, [msg] ]
66
70
  end # case Exception
67
71
  end # method caught
@@ -23,3 +23,5 @@
23
23
  :ROOT_RESOURCE_ACCEPT: [ foo_bar, errors ]
24
24
  # These are the resources which cannot be accessed from the root of your web service. Use either this or ROOT_RESOURCE_ACCEPT as a blacklist or whitelist to establish routing (relationships defined in resource controllers define further routing).
25
25
  :ROOT_RESOURCE_DENY: [ baz ]
26
+
27
+ :SHOW_STACK: true
@@ -162,7 +162,6 @@ class SampleApp::TestControllerActions < Test::Unit::TestCase
162
162
  output = @ws.call(env)
163
163
  end
164
164
  assert_equal response_code, output[0]
165
- #assert_equal 'tester', JSON.parse(output[2][0])[0]
166
165
  end
167
166
 
168
167
  def test_server_error_with_backtrace
@@ -179,4 +178,20 @@ class SampleApp::TestControllerActions < Test::Unit::TestCase
179
178
  assert_not_equal 'tester', output[2][0]
180
179
  end
181
180
 
181
+ def test_server_error_without_backtrace
182
+ RESTRack::CONFIG[:SHOW_STACK] = false
183
+ response_code = 500
184
+ # This will/should spam the log
185
+ env = Rack::MockRequest.env_for('/errors/server_error', {
186
+ :method => 'GET'
187
+ })
188
+ output = ''
189
+ assert_nothing_raised do
190
+ output = @ws.call(env)
191
+ end
192
+ assert_equal response_code, output[0]
193
+ assert_equal 'tester', JSON.parse(output[2][0])[0]
194
+ RESTRack::CONFIG[:SHOW_STACK] = true
195
+ end
196
+
182
197
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restrack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 1.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-14 00:00:00.000000000Z
12
+ date: 2012-02-22 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
- requirement: &18278280 !ruby/object:Gem::Requirement
16
+ requirement: &20404520 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *18278280
24
+ version_requirements: *20404520
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rack-test
27
- requirement: &18277860 !ruby/object:Gem::Requirement
27
+ requirement: &20404080 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *18277860
35
+ version_requirements: *20404080
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: i18n
38
- requirement: &18277440 !ruby/object:Gem::Requirement
38
+ requirement: &20403480 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *18277440
46
+ version_requirements: *20403480
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: json
49
- requirement: &18277020 !ruby/object:Gem::Requirement
49
+ requirement: &20402860 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *18277020
57
+ version_requirements: *20402860
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: xml-simple
60
- requirement: &18328880 !ruby/object:Gem::Requirement
60
+ requirement: &20402080 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.0.13
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *18328880
68
+ version_requirements: *20402080
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: builder
71
- requirement: &18328460 !ruby/object:Gem::Requirement
71
+ requirement: &20384600 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *18328460
79
+ version_requirements: *20384600
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: activesupport
82
- requirement: &18328000 !ruby/object:Gem::Requirement
82
+ requirement: &20383940 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *18328000
90
+ version_requirements: *20383940
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: mime-types
93
- requirement: &18327580 !ruby/object:Gem::Requirement
93
+ requirement: &20383300 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :runtime
100
100
  prerelease: false
101
- version_requirements: *18327580
101
+ version_requirements: *20383300
102
102
  description: ! "\nRESTRack is a Rack-based MVC framework that makes it extremely easy
103
103
  to develop RESTful data services. It is inspired by\nRails, and follows a few of
104
104
  its conventions. But it has no routes file, routing relationships are done through\nsupplying