rest-core 0.8.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +4 -2
- data/CHANGES.md +130 -19
- data/Gemfile +4 -0
- data/README.md +147 -13
- data/TODO.md +0 -10
- data/doc/ToC.md +7 -0
- data/doc/dependency.md +4 -0
- data/doc/design.md +4 -0
- data/example/auto.rb +51 -0
- data/example/coolio.rb +21 -0
- data/example/eventmachine.rb +28 -0
- data/example/multi.rb +33 -0
- data/example/rest-client.rb +16 -0
- data/lib/rest-core/app/abstract/async_fiber.rb +13 -0
- data/lib/rest-core/app/auto.rb +22 -0
- data/lib/rest-core/app/coolio-async.rb +32 -0
- data/lib/rest-core/app/coolio-fiber.rb +30 -0
- data/lib/rest-core/app/coolio.rb +9 -0
- data/lib/rest-core/app/dry.rb +1 -0
- data/lib/rest-core/app/em-http-request-async.rb +34 -0
- data/lib/rest-core/app/em-http-request-fiber.rb +39 -0
- data/lib/rest-core/app/em-http-request.rb +9 -0
- data/lib/rest-core/app/rest-client.rb +24 -7
- data/lib/rest-core/client/universal.rb +3 -4
- data/lib/rest-core/client.rb +31 -4
- data/lib/rest-core/middleware/cache.rb +23 -5
- data/lib/rest-core/middleware/common_logger.rb +13 -3
- data/lib/rest-core/middleware/error_detector.rb +10 -1
- data/lib/rest-core/middleware/error_handler.rb +7 -1
- data/lib/rest-core/middleware/follow_redirect.rb +42 -0
- data/lib/rest-core/middleware/json_decode.rb +11 -2
- data/lib/rest-core/middleware/timeout/coolio_timer.rb +4 -0
- data/lib/rest-core/middleware/timeout/eventmachine_timer.rb +14 -0
- data/lib/rest-core/middleware/timeout.rb +73 -1
- data/lib/rest-core/middleware.rb +7 -0
- data/lib/rest-core/patch/rest-client.rb +35 -0
- data/lib/rest-core/version.rb +1 -1
- data/lib/rest-core.rb +19 -0
- data/rest-core.gemspec +28 -8
- data/test/test_client.rb +20 -3
- data/test/test_follow_redirect.rb +47 -0
- data/test/test_json_decode.rb +24 -0
- metadata +36 -11
- data/example/facebook.rb +0 -9
- data/example/github.rb +0 -4
- data/example/linkedin.rb +0 -8
- data/example/twitter.rb +0 -11
data/.travis.yml
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
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
|
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
|
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 [](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
|
6
|
-
The slide is in English, but the
|
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]:
|
30
|
-
[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
|
-
|
35
|
-
|
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 ,
|
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
|
-
|
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][]
|
73
|
-
and [slides][] from [rubyconf.tw/2011][rubyconf.tw]
|
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
data/doc/ToC.md
ADDED
data/doc/dependency.md
ADDED
data/doc/design.md
ADDED
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
|