rest-core 0.8.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.travis.yml +4 -2
  2. data/CHANGES.md +130 -19
  3. data/Gemfile +4 -0
  4. data/README.md +147 -13
  5. data/TODO.md +0 -10
  6. data/doc/ToC.md +7 -0
  7. data/doc/dependency.md +4 -0
  8. data/doc/design.md +4 -0
  9. data/example/auto.rb +51 -0
  10. data/example/coolio.rb +21 -0
  11. data/example/eventmachine.rb +28 -0
  12. data/example/multi.rb +33 -0
  13. data/example/rest-client.rb +16 -0
  14. data/lib/rest-core/app/abstract/async_fiber.rb +13 -0
  15. data/lib/rest-core/app/auto.rb +22 -0
  16. data/lib/rest-core/app/coolio-async.rb +32 -0
  17. data/lib/rest-core/app/coolio-fiber.rb +30 -0
  18. data/lib/rest-core/app/coolio.rb +9 -0
  19. data/lib/rest-core/app/dry.rb +1 -0
  20. data/lib/rest-core/app/em-http-request-async.rb +34 -0
  21. data/lib/rest-core/app/em-http-request-fiber.rb +39 -0
  22. data/lib/rest-core/app/em-http-request.rb +9 -0
  23. data/lib/rest-core/app/rest-client.rb +24 -7
  24. data/lib/rest-core/client/universal.rb +3 -4
  25. data/lib/rest-core/client.rb +31 -4
  26. data/lib/rest-core/middleware/cache.rb +23 -5
  27. data/lib/rest-core/middleware/common_logger.rb +13 -3
  28. data/lib/rest-core/middleware/error_detector.rb +10 -1
  29. data/lib/rest-core/middleware/error_handler.rb +7 -1
  30. data/lib/rest-core/middleware/follow_redirect.rb +42 -0
  31. data/lib/rest-core/middleware/json_decode.rb +11 -2
  32. data/lib/rest-core/middleware/timeout/coolio_timer.rb +4 -0
  33. data/lib/rest-core/middleware/timeout/eventmachine_timer.rb +14 -0
  34. data/lib/rest-core/middleware/timeout.rb +73 -1
  35. data/lib/rest-core/middleware.rb +7 -0
  36. data/lib/rest-core/patch/rest-client.rb +35 -0
  37. data/lib/rest-core/version.rb +1 -1
  38. data/lib/rest-core.rb +19 -0
  39. data/rest-core.gemspec +28 -8
  40. data/test/test_client.rb +20 -3
  41. data/test/test_follow_redirect.rb +47 -0
  42. data/test/test_json_decode.rb +24 -0
  43. metadata +36 -11
  44. data/example/facebook.rb +0 -9
  45. data/example/github.rb +0 -4
  46. data/example/linkedin.rb +0 -8
  47. data/example/twitter.rb +0 -11
data/.travis.yml CHANGED
@@ -1,4 +1,5 @@
1
- script: 'git submodule update --init; bundle exec rake test'
1
+ before_install: 'git submodule update --init'
2
+ script: 'bundle exec rake test'
2
3
 
3
4
  rvm:
4
5
  - 1.8.7
@@ -6,4 +7,5 @@ rvm:
6
7
  - 1.9.3
7
8
  - rbx-18mode
8
9
  - rbx-19mode
9
- - jruby
10
+ - jruby-18mode
11
+ - jruby-19mode
data/CHANGES.md CHANGED
@@ -1,33 +1,143 @@
1
1
  # CHANGES
2
2
 
3
+ ## rest-core 1.0.0 -- 2012-03-17
4
+
5
+ This is a very significant release. The most important change is now we
6
+ support asynchronous requests, by either passing a callback block or using
7
+ fibers in Ruby 1.9 to make the whole program still look synchronous.
8
+
9
+ Please read [README.md](https://github.com/cardinalblue/rest-core/blob/master/README.md)
10
+ or [example](https://github.com/cardinalblue/rest-core/blob/master/example)
11
+ for more detail.
12
+
13
+ * [`Client`] Client#inspect is fixed for clients which do not have any
14
+ attributes.
15
+
16
+ * [`Client`] HEAD, OPTIONS, and PATCH requests are added. For example:
17
+
18
+ ``` ruby
19
+ client = Client.new
20
+ client.head('path')
21
+ client.options('path')
22
+ client.patch('path')
23
+ ```
24
+
25
+ * [`Client`] Now if you passed a block to either `get` or `post` or other
26
+ requests, the response would be returned to the block instead the caller.
27
+ In this case, the return value of `get` or `post` would be the client
28
+ itself. For example:
29
+
30
+ ``` ruby
31
+ client = Client.new
32
+ client.get('path'){ |response| puts response.insepct }.
33
+ get('math'){ |response| puts response.insepct }
34
+ ```
35
+
36
+ * [`RestClient`] Now all the response headers names are converted to upper
37
+ cases and underscores (_). Also, if a header has only presented once, it
38
+ would not be wrapped inside an array. This is more consistent with
39
+ em-http-request, cool.io-http, and http_parser.rb
40
+
41
+ * [`RestClient`] From now on, the default HTTP client, i.e. `RestClient` won't
42
+ follow any redirect. To follow redirect, please use `FollowRedirect`
43
+ middleware. Two reasons. One is that the underlying HTTP client should
44
+ be minimal. Another one is that a FollowRedirect middleware could be
45
+ used for all HTTP clients. This would make it more consistent across
46
+ all HTTP clients.
47
+
48
+ * [`RestClient`] Added a patch to avoid `"123".to_i` returning `200`,
49
+ please see: <https://github.com/archiloque/rest-client/pull/103>
50
+ I would remove this once after this patch is merged.
51
+
52
+ * [`RestClient`] Added a patch to properly returning response whenever
53
+ a redirect is happened. Please see:
54
+ <https://github.com/archiloque/rest-client/pull/118>
55
+ I would remove this once after this patch is merged.
56
+
57
+ * [`FollowRedirect`] This middleware would follow the redirect. Pass
58
+ :max_redirects for the maximum redirect times. For example:
59
+
60
+ ``` ruby
61
+ Client = RestCore::Builder.client do
62
+ use FollowRedirect, 2 # default :max_redirects
63
+ end
64
+ client = Client.new
65
+ client.get('path', {}, :max_redirects => 5)
66
+ ```
67
+
68
+ * [`Middleware`] Added `Middleware#run` which can return the underlying HTTP
69
+ client, if you need to know the underlying HTTP client can support
70
+ asynchronous requests or not.
71
+
72
+ * [`Cache`] Now it's asynchrony-aware.
73
+ * [`CommonLogger`] Now it's asynchrony-aware.
74
+ * [`ErrorDetector`] Now it's asynchrony-aware.
75
+ * [`ErrorHandler`] Now it's asynchrony-aware.
76
+ * [`JsonDecode`] Now it's asynchrony-aware.
77
+ * [`Timeout`] Now it's asynchrony-aware.
78
+
79
+ * [`Universal`] `FollowRedirect` middleware is added.
80
+ * [`Universal`] `Defaults` middleware is removed.
81
+
82
+ * Added `RestCore::ASYNC` which should be the callback function which is
83
+ called whenever the response is available. It's similar to Rack's
84
+ async.callback.
85
+
86
+ * Added `RestCore::TIMER` which is only used in Timeout middleware. We need
87
+ this to disable timer whenever the response is back.
88
+
89
+ * [`EmHttpRequestAsync`] This HTTP client accepts a block to make asynchronous
90
+ HTTP requests via em-http-request gem.
91
+
92
+ * [`EmHttpRequestFiber`] This HTTP client would make asynchronous HTTP
93
+ requests with em-http-request but also wrapped inside a fiber, so that it
94
+ looks synchronous to the program who calls it.
95
+
96
+ * [`EmHttpRequest`] This HTTP client would would use `EmHttpRequestAsync` if
97
+ a block (`RestCore::ASYNC`) is passed, otherwise use `EmHttpRequestFiber`.
98
+
99
+ * [`CoolioAsync`] This HTTP client is basically the same as
100
+ `EmHttpRequestAsync`, but using cool.io-http instead of em-http-request.
101
+
102
+ * [`CoolioFiber`] This HTTP client is basically the same as
103
+ `EmHttpRequestFiber`, but using cool.io-http instead of em-http-request.
104
+
105
+ * [`Coolio`] This HTTP client is basically the same as `EmHttpRequest`,
106
+ but using cool.io-http instead of em-http-request.
107
+
108
+ * [`Auto`] This HTTP client would auto-select a suitable client. Under
109
+ eventmachine, it would use `EmHttpRequest`. Under cool.io, it would use
110
+ `Coolio`. Otherwise, it would use `RestClient`.
111
+
3
112
  ## rest-core 0.8.2 -- 2012-02-18
4
113
 
5
114
  ### Enhancement
6
115
 
7
- * [DefaultPayload] This middleware allows you to have default payload for
116
+ * [`DefaultPayload`] This middleware allows you to have default payload for
8
117
  POST and PUT requests.
9
118
 
10
- * [Client] Now `lighten` would give all Unserializable to nil instead of false
119
+ * [`Client`] Now `lighten` would give all Unserializable to nil instead of
120
+ false
11
121
 
12
122
  ### Bugs fixes
13
123
 
14
- * [ErrorDetector] Now it would do nothing instead of crashing if there's no
124
+ * [`ErrorDetector`] Now it would do nothing instead of crashing if there's no
15
125
  any error_detector.
16
126
 
17
127
  ## rest-core 0.8.1 -- 2012-02-09
18
128
 
19
129
  ### Enhancement
20
130
 
21
- * [Wrapper] Introducing `Wrapper.default_app` (also `Builder.default_app`)
131
+ * [`Wrapper`] Introducing `Wrapper.default_app` (also `Builder.default_app`)
22
132
  which you can change the default app from `RestClient` to other HTTP
23
133
  clients.
24
134
 
25
135
  ### Bugs fixes
26
136
 
27
- * [OAuth1Header] Correctly handle the signature when it comes to multipart
137
+ * [`OAuth1Header`] Correctly handle the signature when it comes to multipart
28
138
  requests.
29
139
 
30
- * [ErrorDetectorHttp] Fixed argument error upon calling `lighten` for
140
+ * [`ErrorDetectorHttp`] Fixed argument error upon calling `lighten` for
31
141
  clients using this middleware. (e.g. rest-more's Twitter client)
32
142
 
33
143
  ## rest-core 0.8.0 -- 2011-11-29
@@ -36,16 +146,16 @@ Changes are mostly related to OAuth.
36
146
 
37
147
  ### Incompatible changes
38
148
 
39
- * [OAuth1Header] `callback` is renamed to `oauth_callback`
40
- * [OAuth1Header] `verifier` is renamed to `oauth_verifier`
149
+ * [`OAuth1Header`] `callback` is renamed to `oauth_callback`
150
+ * [`OAuth1Header`] `verifier` is renamed to `oauth_verifier`
41
151
 
42
- * [Oauth2Header] The first argument is changed from `access_token` to
152
+ * [`Oauth2Header`] The first argument is changed from `access_token` to
43
153
  `access_token_type`. Previously, the access_token_type is "OAuth" which
44
154
  is used in Mixi. But mostly, we might want to use "Bearer" (according to
45
155
  [OAuth 2.0 spec][]) Argument for the access_token is changed to the second
46
156
  argument.
47
157
 
48
- * [Defaults] Now we're no longer call `call` for any default values.
158
+ * [`Defaults`] Now we're no longer call `call` for any default values.
49
159
  That is, if you're using this: `use s::Defaults, :data => lambda{{}}`
50
160
  that would break. Previously, this middleware would call `call` on the
51
161
  lambda so that `data` is default to a newly created hash. Now, it would
@@ -57,35 +167,36 @@ Changes are mostly related to OAuth.
57
167
 
58
168
  ### Enhancement
59
169
 
60
- * [AuthBasic] Added a new middleware which could do [basic authentication][].
170
+ * [`AuthBasic`] Added a new middleware which could do
171
+ [basic authentication][].
61
172
 
62
- * [OAuth1Header] Introduced `data` which is a hash and is used to store
173
+ * [`OAuth1Header`] Introduced `data` which is a hash and is used to store
63
174
  tokens and other information sent from authorization servers.
64
175
 
65
- * [ClientOauth1] Now `authorize_url!` accepts opts which you can pass
176
+ * [`ClientOauth1`] Now `authorize_url!` accepts opts which you can pass
66
177
  `authorize_url!(:oauth_callback => 'http://localhost/callback')`.
67
178
 
68
- * [ClientOauth1] Introduced `authorize_url` which would not try to ask
179
+ * [`ClientOauth1`] Introduced `authorize_url` which would not try to ask
69
180
  for a request token, instead, it would use the current token as the
70
181
  request token. If you don't understand what does this mean, then keep
71
182
  using `authorize_url!`, which would call this underneath.
72
183
 
73
- * [ClientOauth1] Introduced `authorized?`
74
- * [ClientOauth1] Now it would set `data['authorized'] = 'true'` when
184
+ * [`ClientOauth1`] Introduced `authorized?`
185
+ * [`ClientOauth1`] Now it would set `data['authorized'] = 'true'` when
75
186
  `authorize!` is called, and it is also used to check if we're authorized
76
187
  or not in `authorized?`
77
188
 
78
- * [ClientOauth1] Introduced `data_json` and `data_json=` which allow you to
189
+ * [`ClientOauth1`] Introduced `data_json` and `data_json=` which allow you to
79
190
  serialize and deserialize `data` with JSON along with a `sig` to check
80
191
  if it hasn't been changed. You can put this into browser cookie. Because
81
192
  of the `sig`, you would know if the user changed something in data without
82
193
  using `consumer_secret` to generate a correct sig corresponded to the data.
83
194
 
84
- * [ClientOauth1] Introduced `oauth_token`, `oauth_token=`,
195
+ * [`ClientOauth1`] Introduced `oauth_token`, `oauth_token=`,
85
196
  `oauth_token_secret`, `oauth_token_secret=`, `oauth_callback`,
86
197
  and `oauth_callback=` which take the advantage of `data`.
87
198
 
88
- * [ClientOauth1] Introduced `default_data` which is a hash.
199
+ * [`ClientOauth1`] Introduced `default_data` which is a hash.
89
200
 
90
201
  [basic authentication]: http://en.wikipedia.org/wiki/Basic_access_authentication
91
202
 
data/Gemfile CHANGED
@@ -3,6 +3,9 @@ source 'http://rubygems.org'
3
3
 
4
4
  gemspec
5
5
 
6
+ gem 'rest-client'
7
+ gem 'em-http-request'
8
+
6
9
  gem 'rake'
7
10
  gem 'bacon'
8
11
  gem 'rr'
@@ -16,6 +19,7 @@ gem 'ruby-hmac'
16
19
 
17
20
  platforms(:ruby) do
18
21
  gem 'yajl-ruby'
22
+ gem 'cool.io-http'
19
23
  end
20
24
 
21
25
  platforms(:jruby) do
data/README.md CHANGED
@@ -1,9 +1,12 @@
1
- # rest-core [![Build Status](http://travis-ci.org/godfat/rest-core.png)](http://travis-ci.org/godfat/rest-core)
1
+ # rest-core [![Build Status](https://secure.travis-ci.org/godfat/rest-core.png?branch=master)](http://travis-ci.org/godfat/rest-core)
2
2
 
3
3
  by Cardinal Blue <http://cardinalblue.com>
4
4
 
5
- Lin Jen-Shin ([godfat][]) had given a talk about rest-core on [RubyConf Taiwan 2011][talk].
6
- The slide is in English, but the talk is in Mandarin.
5
+ Lin Jen-Shin ([godfat][]) had given a talk about rest-core on
6
+ [RubyConf Taiwan 2011][talk]. The slide is in English, but the
7
+ talk is in Mandarin.
8
+
9
+ You can also read some other topics at [doc](https://github.com/cardinalblue/rest-core/blob/master/doc/ToC.md).
7
10
 
8
11
  [godfat]: https://github.com/godfat
9
12
  [talk]: http://rubyconf.tw/2011/#6
@@ -26,13 +29,30 @@ that allows you to build a REST client for any REST API. Or in the case of
26
29
  common APIs such as Facebook, Github, and Twitter, you can simply use the
27
30
  dedicated clients provided by [rest-more][].
28
31
 
29
- [rest-core]: http://github.com/cardinalblue/rest-core
30
- [rest-more]: http://github.com/cardinalblue/rest-more
32
+ [rest-core]: https://github.com/cardinalblue/rest-core
33
+ [rest-more]: https://github.com/cardinalblue/rest-more
34
+
35
+ ## FEATURES:
36
+
37
+ * Modular interface for REST clients similar to WSGI/Rack for servers.
38
+ * Asynchronous/Synchronous styles with or without fibers are both supported.
31
39
 
32
40
  ## REQUIREMENTS:
33
41
 
34
- * Tested with MRI (official CRuby) 1.8.7, 1.9.2, 1.9.3, Rubinius and JRuby
35
- * gem rest-client (for now)
42
+ ### Mandatory:
43
+
44
+ * MRI (official CRuby) 1.8.7, 1.9.2, 1.9.3, Rubinius 1.8/1.9 and JRuby 1.8/1.9
45
+ * gem rest-client
46
+
47
+ ### Optional:
48
+
49
+ * Fibers only work on Ruby 1.9+
50
+ * gem [em-http-request][] (if using eventmachine)
51
+ * gem [cool.io-http][] (if using cool.io)
52
+ * gem json or yajl-ruby (if using JsonDecode middleware)
53
+
54
+ [em-http-request]: https://github.com/igrigorik/em-http-request
55
+ [cool.io-http]: https://github.com/godfat/cool.io-http
36
56
 
37
57
  ## INSTALLATION:
38
58
 
@@ -40,8 +60,10 @@ dedicated clients provided by [rest-more][].
40
60
 
41
61
  Or if you want development version, put this in Gemfile:
42
62
 
63
+ ``` ruby
43
64
  gem 'rest-core', :git => 'git://github.com/cardinalblue/rest-core.git',
44
65
  :submodules => true
66
+ ```
45
67
 
46
68
  If you just want to use Facebook or Twitter clients, please take a look at
47
69
  [rest-more][] which has a lot of clients built with rest-core.
@@ -50,6 +72,9 @@ If you just want to use Facebook or Twitter clients, please take a look at
50
72
 
51
73
  ## Build Your Own Clients:
52
74
 
75
+ You can use `RestCore::Builder` to build your own dedicated client:
76
+
77
+ ``` ruby
53
78
  require 'rest-core'
54
79
 
55
80
  YourClient = RestCore::Builder.client do
@@ -57,31 +82,140 @@ If you just want to use Facebook or Twitter clients, please take a look at
57
82
  use s::DefaultSite , 'https://api.github.com/users/'
58
83
  use s::JsonDecode , true
59
84
  use s::CommonLogger, method(:puts)
60
- use s::Cache , {}, 3600
61
- run s::RestClient
85
+ use s::Cache , nil, 3600
86
+ run s::RestClient # the simplest and easier HTTP client
62
87
  end
88
+ ```
63
89
 
64
- client = YourClient.new
90
+ And use it with per-instance basis (clients could have different
91
+ configuration, e.g. different cache time or timeout time):
92
+
93
+ ``` ruby
94
+ client = YourClient.new(:cache => {})
65
95
  client.get('cardinalblue') # cache miss
66
96
  client.get('cardinalblue') # cache hit
67
97
 
68
98
  client.site = 'http://github.com/api/v2/json/user/show/'
69
99
  client.get('cardinalblue') # cache miss
70
100
  client.get('cardinalblue') # cache hit
101
+ ```
71
102
 
72
- Please see [rest-more][] for more complex examples,
73
- and [slides][] from [rubyconf.tw/2011][rubyconf.tw] for concepts.
103
+ Runnable example is here: [example/rest-client.rb][]. Please see [rest-more][]
104
+ for more complex examples, and [slides][] from [rubyconf.tw/2011][rubyconf.tw]
105
+ for concepts.
74
106
 
107
+ [example/rest-client.rb]: https://github.com/cardinalblue/rest-core/blob/master/example/rest-client.rb
75
108
  [rest-more]: https://github.com/cardinalblue/rest-more
76
109
  [rubyconf.tw]: http://rubyconf.tw/2011/#6
77
110
  [slides]: http://www.godfat.org/slide/2011-08-27-rest-core.html
78
111
 
112
+ ## Asynchronous HTTP Requests:
113
+
114
+ I/O bound operations shouldn't be blocking the CPU! If you have a reactor,
115
+ i.e. event loop, you should take the advantage of that to make HTTP requests
116
+ non-blocking the whole process/thread. For now, we support eventmachine and
117
+ cool.io. Below is an example for eventmachine:
118
+
119
+ ``` ruby
120
+ require 'rest-core'
121
+
122
+ AsynchronousClient = RestCore::Builder.client do
123
+ s = self.class # this is only for ruby 1.8!
124
+ use s::DefaultSite , 'https://api.github.com/users/'
125
+ use s::JsonDecode , true
126
+ use s::CommonLogger, method(:puts)
127
+ use s::Cache , nil, 3600
128
+ run s::EmHttpRequest
129
+ end
130
+ ```
131
+
132
+ If you're passing a block, the block is called after the response is
133
+ available. That is the block is the callback for the request.
134
+
135
+ ``` ruby
136
+ client = AsynchronousClient.new(:cache => {})
137
+ EM.run{
138
+ client.get('cardinalblue'){ |response|
139
+ p response
140
+ EM.stop
141
+ }
142
+ }
143
+ ```
144
+
145
+ Otherwise, if you don't pass a block as the callback, EmHttpRequest (i.e.
146
+ the HTTP client for eventmachine) would call `Fiber.yield` to yield to the
147
+ original fiber, making asynchronous HTTP requests look like synchronous.
148
+ If you don't understand what does this mean, you can take a look at
149
+ [em-synchrony][]. It's basically the same idea.
150
+
151
+ ``` ruby
152
+ EM.run{
153
+ Fiber.new{
154
+ p client.get('cardinalblue')
155
+ EM.stop
156
+ }.resume
157
+ }
158
+ ```
159
+
160
+ [em-synchrony]: https://github.com/igrigorik/em-synchrony
161
+
162
+ Runnable example is here: [example/eventmachine.rb][].
163
+ You can also make multi-requests synchronously like this:
164
+
165
+ ``` ruby
166
+ EM.run{
167
+ Fiber.new{
168
+ fiber = Fiber.current
169
+ result = {}
170
+ client.get('cardinalblue'){ |response|
171
+ result[0] = response
172
+ fiber.resume(result) if result.size == 2
173
+ }
174
+ client.get('cardinalblue'){ |response|
175
+ result[1] = response
176
+ fiber.resume(result) if result.size == 2
177
+ }
178
+ p Fiber.yield
179
+ EM.stop
180
+ }.resume
181
+ }
182
+ ```
183
+
184
+ Runnable example is here: [example/multi.rb][].
185
+
186
+ [example/eventmachine.rb]: https://github.com/cardinalblue/rest-core/blob/master/example/eventmachine.rb
187
+ [example/multi.rb]: https://github.com/cardinalblue/rest-core/blob/master/example/multi.rb
188
+
189
+ ## Supported HTTP clients:
190
+
191
+ * `RestCore::RestClient` (gem rest-client)
192
+ * `RestCore::EmHttpRequest` (gem em-http-request)
193
+ * `RestCore::Coolio` (gem cool.io)
194
+ * `RestCore::Auto` (which would pick one of the above depending on the
195
+ context)
196
+
197
+ ## Build Your Own Middlewares:
198
+
199
+ To be added.
200
+
201
+ ## Build Your Own HTTP clients:
202
+
203
+ To be added.
204
+
79
205
  ## rest-core users:
80
206
 
81
207
  * [topcoder](https://github.com/miaout17/topcoder)
82
208
  * [s2sync](https://github.com/brucehsu/s2sync)
83
209
  * [s2sync_web](https://github.com/brucehsu/s2sync_web)
84
210
 
211
+ ## Powered sites:
212
+
213
+ * [PicCollage](http://pic-collage.com/)
214
+
215
+ ## CHANGES:
216
+
217
+ * [CHANGES](https://github.com/cardinalblue/rest-core/blob/master/CHANGES.md)
218
+
85
219
  ## GLOSSARY:
86
220
 
87
221
  * A _client_ is a class which can new connections to make requests.
@@ -184,7 +318,7 @@ and [slides][] from [rubyconf.tw/2011][rubyconf.tw] for concepts.
184
318
 
185
319
  Apache License 2.0
186
320
 
187
- Copyright (c) 2011, Cardinal Blue
321
+ Copyright (c) 2011-2012, Cardinal Blue
188
322
 
189
323
  Licensed under the Apache License, Version 2.0 (the "License");
190
324
  you may not use this file except in compliance with the License.
data/TODO.md CHANGED
@@ -1,14 +1,4 @@
1
1
  # TODO
2
2
 
3
- ## high
4
-
5
3
  * middleware revisit (how to initialize?)
6
-
7
- ## medium
8
-
9
- * what about async request? yield callback? coroutine?
10
- * dependency?
11
-
12
- ## low
13
-
14
4
  * test utility
data/doc/ToC.md ADDED
@@ -0,0 +1,7 @@
1
+
2
+ # rest-core documentation
3
+
4
+ ## Table of Content
5
+
6
+ * [Overview and Design Concept](design.md)
7
+ * [Picking Dependency](dependency.md)
data/doc/dependency.md ADDED
@@ -0,0 +1,4 @@
1
+
2
+ # Picking Dependency
3
+
4
+
data/doc/design.md ADDED
@@ -0,0 +1,4 @@
1
+
2
+ # Overview and Design Concept
3
+
4
+
data/example/auto.rb ADDED
@@ -0,0 +1,51 @@
1
+
2
+ require 'rest-core'
3
+ require 'eventmachine'
4
+ require 'cool.io'
5
+
6
+ YourClient = RestCore::Builder.client do
7
+ s = self.class # this is only for ruby 1.8!
8
+ use s::DefaultSite , 'https://api.github.com/users/'
9
+ use s::JsonDecode , true
10
+ use s::CommonLogger, method(:puts)
11
+ use s::Cache , nil, 3600
12
+ run s::Auto
13
+ end
14
+
15
+ client = YourClient.new(:cache => {})
16
+ p client.get('cardinalblue') # cache miss
17
+ puts
18
+ p client.get('cardinalblue') # cache hit
19
+
20
+ puts
21
+
22
+ client = YourClient.new(:cache => {})
23
+ EM.run{
24
+ client.get('cardinalblue'){ |response|
25
+ p response
26
+ EM.stop
27
+ }
28
+ }
29
+
30
+ puts
31
+
32
+ EM.run{
33
+ Fiber.new{
34
+ p client.get('cardinalblue')
35
+ EM.stop
36
+ }.resume
37
+ }
38
+
39
+ puts
40
+
41
+ client = YourClient.new(:cache => {})
42
+ Coolio::TimerWatcher.new(1).attach(Coolio::Loop.default).on_timer{detach}
43
+ client.get('cardinalblue'){ |response|
44
+ p response
45
+ }
46
+ Coolio::Loop.default.run
47
+
48
+ puts
49
+ Coolio::TimerWatcher.new(1).attach(Coolio::Loop.default).on_timer{detach}
50
+ Fiber.new{ p client.get('cardinalblue') }.resume
51
+ Coolio::Loop.default.run
data/example/coolio.rb ADDED
@@ -0,0 +1,21 @@
1
+
2
+ require 'rest-core'
3
+
4
+ AsynchronousClient = RestCore::Builder.client do
5
+ s = self.class # this is only for ruby 1.8!
6
+ use s::DefaultSite , 'https://api.github.com/users/'
7
+ use s::JsonDecode , true
8
+ use s::CommonLogger, method(:puts)
9
+ use s::Cache , nil, 3600
10
+ run s::Coolio
11
+ end
12
+
13
+ AsynchronousClient.new.get('cardinalblue'){ |response|
14
+ p response
15
+ }
16
+ Coolio::Loop.default.run
17
+
18
+ puts
19
+
20
+ Fiber.new{ p AsynchronousClient.new.get('cardinalblue') }.resume
21
+ Coolio::Loop.default.run
@@ -0,0 +1,28 @@
1
+
2
+ require 'rest-core'
3
+
4
+ AsynchronousClient = RestCore::Builder.client do
5
+ s = self.class # this is only for ruby 1.8!
6
+ use s::DefaultSite , 'https://api.github.com/users/'
7
+ use s::JsonDecode , true
8
+ use s::CommonLogger, method(:puts)
9
+ use s::Cache , nil, 3600
10
+ run s::EmHttpRequest
11
+ end
12
+
13
+ client = AsynchronousClient.new(:cache => {})
14
+ EM.run{
15
+ client.get('cardinalblue'){ |response|
16
+ p response
17
+ EM.stop
18
+ }
19
+ }
20
+
21
+ puts
22
+
23
+ EM.run{
24
+ Fiber.new{
25
+ p client.get('cardinalblue')
26
+ EM.stop
27
+ }.resume
28
+ }
data/example/multi.rb ADDED
@@ -0,0 +1,33 @@
1
+
2
+ require 'rest-core'
3
+ require 'eventmachine'
4
+ RestCore::EmHttpRequest # there might be a autoload bug?
5
+ # omitting this line would cause
6
+ # stack level too deep (SystemStackError)
7
+
8
+ YourClient = RestCore::Builder.client do
9
+ s = self.class # this is only for ruby 1.8!
10
+ use s::DefaultSite , 'https://api.github.com/users/'
11
+ use s::JsonDecode , true
12
+ use s::CommonLogger, method(:puts)
13
+ use s::Cache , nil, 3600
14
+ run s::Auto
15
+ end
16
+
17
+ client = YourClient.new
18
+ EM.run{
19
+ Fiber.new{
20
+ fiber = Fiber.current
21
+ result = {}
22
+ client.get('cardinalblue'){ |response|
23
+ result[0] = response
24
+ fiber.resume(result) if result.size == 2
25
+ }
26
+ client.get('cardinalblue'){ |response|
27
+ result[1] = response
28
+ fiber.resume(result) if result.size == 2
29
+ }
30
+ p Fiber.yield
31
+ EM.stop
32
+ }.resume
33
+ }
@@ -0,0 +1,16 @@
1
+
2
+ require 'rest-core'
3
+
4
+ YourClient = RestCore::Builder.client do
5
+ s = self.class # this is only for ruby 1.8!
6
+ use s::DefaultSite , 'https://api.github.com/users/'
7
+ use s::JsonDecode , true
8
+ use s::CommonLogger, method(:puts)
9
+ use s::Cache , nil, 3600
10
+ run s::RestClient
11
+ end
12
+
13
+ client = YourClient.new(:cache => {})
14
+ p client.get('cardinalblue') # cache miss
15
+ puts
16
+ p client.get('cardinalblue') # cache hit
@@ -0,0 +1,13 @@
1
+
2
+ require 'rest-core/middleware'
3
+
4
+ class RestCore::AsyncFiber
5
+ include RestCore::Middleware
6
+ def call env
7
+ if env[ASYNC]
8
+ async.call(env)
9
+ else
10
+ fiber.call(env)
11
+ end
12
+ end
13
+ end