restrack 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown.html +282 -0
- data/lib/restrack/version.rb +1 -1
- data/lib/restrack/web_service.rb +0 -3
- data/restrack.komodoproject +7 -0
- metadata +4 -2
@@ -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/<controller>/<action>.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><sudo> 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 < 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 <= simple pass-through from Foo 123 to show Bar 234
|
101
|
+
GET /foo/123/bar <= 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 <= direct route to show Sally's spouse
|
120
|
+
PUT /people/Henry/spouse <= direct route to update Henry's spouse
|
121
|
+
POST /people/Jane/spouse <= 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 => 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 <= direct route to show child 0
|
140
|
+
DELETE /people/Robert/children/100 <= 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 => 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 <= route to show child George
|
153
|
+
DELETE /people/Robert/children/Jerry <= 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' => People.find(id).father.id,
|
166
|
+
'mother' => People.find(id).mother.id,
|
167
|
+
'boss' => People.find(id).boss.id,
|
168
|
+
'assistant' => 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 => show the father of Fred
|
176
|
+
PUT /people/Fred/people/assistant => update Fred's assistant
|
177
|
+
POST /people/Fred/people/boss => add Fred's boss
|
178
|
+
DELETE /people/Luke/people/mother => 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/<controller>/<action>.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>
|
data/lib/restrack/version.rb
CHANGED
data/lib/restrack/web_service.rb
CHANGED
@@ -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.
|
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-
|
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
|