rest-core 2.1.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/.travis.yml +3 -5
  4. data/CHANGES.md +65 -5
  5. data/Gemfile +10 -5
  6. data/NOTE.md +1 -1
  7. data/README.md +194 -128
  8. data/Rakefile +8 -34
  9. data/TODO.md +3 -2
  10. data/example/simple.rb +6 -4
  11. data/example/use-cases.rb +39 -122
  12. data/lib/rest-core.rb +14 -5
  13. data/lib/rest-core/builder.rb +12 -2
  14. data/lib/rest-core/client.rb +31 -25
  15. data/lib/rest-core/engine.rb +39 -0
  16. data/lib/rest-core/engine/http-client.rb +41 -0
  17. data/lib/rest-core/engine/net-http-persistent.rb +21 -0
  18. data/lib/rest-core/engine/rest-client.rb +13 -42
  19. data/lib/rest-core/event_source.rb +91 -0
  20. data/lib/rest-core/middleware.rb +17 -11
  21. data/lib/rest-core/middleware/error_detector.rb +1 -6
  22. data/lib/rest-core/middleware/oauth1_header.rb +1 -0
  23. data/lib/rest-core/middleware/oauth2_header.rb +20 -8
  24. data/lib/rest-core/middleware/oauth2_query.rb +1 -0
  25. data/lib/rest-core/middleware/timeout.rb +5 -19
  26. data/lib/rest-core/promise.rb +137 -0
  27. data/lib/rest-core/test.rb +2 -43
  28. data/lib/rest-core/thread_pool.rb +122 -0
  29. data/lib/rest-core/timer.rb +30 -0
  30. data/lib/rest-core/util/hmac.rb +0 -8
  31. data/lib/rest-core/version.rb +1 -1
  32. data/lib/rest-core/wrapper.rb +1 -1
  33. data/rest-core.gemspec +36 -25
  34. data/task/README.md +54 -0
  35. data/task/gemgem.rb +150 -156
  36. data/test/test_builder.rb +2 -2
  37. data/test/test_cache.rb +8 -8
  38. data/test/test_client.rb +16 -6
  39. data/test/test_client_oauth1.rb +1 -1
  40. data/test/test_event_source.rb +77 -0
  41. data/test/test_follow_redirect.rb +1 -1
  42. data/test/test_future.rb +16 -0
  43. data/test/test_oauth2_header.rb +28 -0
  44. data/test/test_promise.rb +89 -0
  45. data/test/test_rest-client.rb +21 -0
  46. data/test/test_thread_pool.rb +10 -0
  47. data/test/test_timeout.rb +13 -8
  48. metadata +61 -37
  49. data/example/multi.rb +0 -44
  50. data/lib/rest-core/engine/auto.rb +0 -25
  51. data/lib/rest-core/engine/em-http-request.rb +0 -90
  52. data/lib/rest-core/engine/future/future.rb +0 -107
  53. data/lib/rest-core/engine/future/future_fiber.rb +0 -32
  54. data/lib/rest-core/engine/future/future_thread.rb +0 -29
  55. data/lib/rest-core/middleware/timeout/timer_em.rb +0 -26
  56. data/lib/rest-core/middleware/timeout/timer_thread.rb +0 -36
  57. data/task/.gitignore +0 -1
  58. data/test/test_em-http-request.rb +0 -186
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 71b8ab944328b862d8a3524a01da91432fe7fcb4
4
- data.tar.gz: 204f46ff9a25281ffdbbe814df50831519a98c88
3
+ metadata.gz: 58ed90f247d23da6267042bf108e50637e8dba98
4
+ data.tar.gz: a0d0b5f7dd766fee5426fc0faf5c5d0dd6adb229
5
5
  SHA512:
6
- metadata.gz: 67d6c4ee4116a562fa5a16a41b6c94b5b4f0c768abc077e78d1b0a416d28146784a9a358208175de212c9ccac3fe3956a00bda5eabfa81ba714beec2aeeaec7e
7
- data.tar.gz: 7f723ab6d7e7b295d24b664aa9ef1ce38d56c39e2c2ef75d34aaded046a8aa97d9fb1b16ecf5a3d1867fba596afb46f4203f250b9f729ccad998dfbf887cb72f
6
+ metadata.gz: a45a9c11e364a08414a7e583feedbe3a289a59fba42aa8d0180e0144e91279b7a77662737c489ec466402a72db4a2833f9e674ad27954d93e325e33713f4766d
7
+ data.tar.gz: 3f3b2e09cd1131543a677e9a61cf4872c70fb272aad936eccd0f005d6490646b6589e0128ffd33f6107b644c77ef772a34f6433bd6c3d37fffe0aa1a53b72010
data/.gitignore CHANGED
@@ -1,2 +1 @@
1
- pkg
2
- *.rbc
1
+ /pkg/
@@ -1,11 +1,9 @@
1
1
  before_install: 'git submodule update --init'
2
2
  script: 'ruby -r bundler/setup -S rake test'
3
3
 
4
- env:
5
- - 'RBXOPT=-X19'
6
-
7
4
  rvm:
8
5
  - 1.9.3
9
6
  - 2.0.0
10
- - rbx-head
11
- - jruby-head
7
+ - ruby
8
+ - rbx
9
+ - jruby
data/CHANGES.md CHANGED
@@ -1,5 +1,65 @@
1
1
  # CHANGES
2
2
 
3
+ ## rest-core 3.0.0 -- ?
4
+
5
+ Highlights:
6
+
7
+ * Hijack for streaming responses
8
+ * EventSource for SSE (server-sent events)
9
+ * Thread pool
10
+ * Keep-alive connections from httpclient
11
+
12
+ ### Incompatible changes
13
+
14
+ * Since eventmachine is buggy, and fibers without eventmachine doesn't make
15
+ too much sense, we have removed the support for eventmachine and fibers.
16
+
17
+ * We also changed the default HTTP client from rest-client to httpclient.
18
+ If you still want to use rest-client, switch it like this:
19
+
20
+ RC::Builder.default_engine = RC::RestClient
21
+
22
+ Be warned, we might remove rest-client support in the future.
23
+
24
+ * `RC::Client#options` would now return the headers instead of response body.
25
+
26
+ * Removed support for Ruby 1.8.7 without openssl installed.
27
+
28
+ * `RC::Future` is renamed to `RC::Promise`, and `RC::Future::Proxy` is
29
+ renamed to `RC::Promise::Future`.
30
+
31
+ ### Enhancement
32
+
33
+ * HIJACK support, which is similar to Rack's HIJACK feature. If you're
34
+ passing `{RC::HIJACK => true}` whenever making a request, rest-core would
35
+ rather set the `RC::RESPONSE_BODY` as an empty string, and set
36
+ `RC::RESPONSE_SOCKET` as a socket for the response. This is used for
37
+ `RC::EventSource`, and you could also use this for streaming the response.
38
+ Note that this only works for default engine, httpclient.
39
+
40
+ * Introduce `RC::EventSource`. You could obtain the object via
41
+ `RC::Client#event_source`, and then setup `onopen`, `onmessage`, and
42
+ `onerror` respectively, and then call `RC::EventSource#start` to begin
43
+ making the request, and receive the SSE (sever-sent events) from the server.
44
+ This is used in `RC::Firebase` from rest-more.
45
+
46
+ * Now we have thread pool support. We could set the pool size with:
47
+ `RC::YourClient.pool_size = 10` and thread idle time with:
48
+ `RC::YourClient.pool_idle_time = 60`. By default, `pool_size` is 0
49
+ which means we don't use a thread pool. Setting it to a negative number
50
+ would mean do not spawn any threads, just make a blocking request.
51
+ `pool_idle_time` is default to 60, meaning an idle thread would be shut
52
+ down after 60 seconds without being used.
53
+
54
+ * Since we're now using httpclient by default, we should also take the
55
+ advantage of using keep-alive connections for the same host.
56
+
57
+ * Now `RC::Middleware#fail` and `RC::Middleware#log` could accept `nil` as
58
+ an input, which would then do nothing. This could much simplify the code
59
+ building middleware.
60
+
61
+ * Now we're using timers gem which should be less buggy from previous timeout.
62
+
3
63
  ## rest-core 2.1.2 -- 2013-05-31
4
64
 
5
65
  ### Incompatible changes
@@ -160,7 +220,7 @@ It's a bit outdated, but you can also checkout my blog post.
160
220
  [rest-core 2.0 roadmap, thunk based response][post]
161
221
  (p.s. now thunk is renamed to future)
162
222
 
163
- [use-cases.rb]: https://github.com/cardinalblue/rest-core/blob/master/example/use-cases.rb
223
+ [use-cases.rb]: https://github.com/godfat/rest-core/blob/master/example/use-cases.rb
164
224
  [post]: http://blogger.godfat.org/2012/06/rest-core-20-roadmap-thunk-based.html
165
225
 
166
226
  ### Incompatible changes
@@ -263,8 +323,8 @@ This is a very significant release. The most important change is now we
263
323
  support asynchronous requests, by either passing a callback block or using
264
324
  fibers in Ruby 1.9 to make the whole program still look synchronous.
265
325
 
266
- Please read [README.md](https://github.com/cardinalblue/rest-core/blob/master/README.md)
267
- or [example](https://github.com/cardinalblue/rest-core/tree/master/example)
326
+ Please read [README.md](https://github.com/godfat/rest-core/blob/master/README.md)
327
+ or [example](https://github.com/godfat/rest-core/tree/master/example)
268
328
  for more detail.
269
329
 
270
330
  * [`Client`] Client#inspect is fixed for clients which do not have any
@@ -472,7 +532,7 @@ others are moved to [rest-more][]. Since bundler didn't like cyclic
472
532
  dependency, so rest-core is not depending on rest-more. Please install
473
533
  _rest-more_ if you want to use them.
474
534
 
475
- [rest-more]: https://github.com/cardinalblue/rest-more
535
+ [rest-more]: https://github.com/godfat/rest-more
476
536
 
477
537
  ## rest-core 0.4.0 -- 2011-09-26
478
538
 
@@ -563,7 +623,7 @@ _rest-more_ if you want to use them.
563
623
  twitter:
564
624
  consumer_key: abc
565
625
 
566
- [rest-graph]: https://github.com/cardinalblue/rest-graph
626
+ [rest-graph]: https://github.com/godfat/rest-graph
567
627
 
568
628
  ## rest-core 0.2.3 -- 2011-08-27
569
629
 
data/Gemfile CHANGED
@@ -4,11 +4,10 @@ source 'https://rubygems.org/'
4
4
  gemspec
5
5
 
6
6
  gem 'rest-client'
7
- gem 'em-http-request'
8
7
 
9
8
  gem 'rake'
10
9
  gem 'bacon'
11
- gem 'rr'
10
+ gem 'muack'
12
11
  gem 'webmock'
13
12
 
14
13
  gem 'json'
@@ -16,12 +15,18 @@ gem 'json_pure'
16
15
  gem 'multi_json'
17
16
 
18
17
  gem 'rack'
19
- gem 'ruby-hmac'
20
18
 
21
- platforms(:ruby) do
19
+ platforms :ruby do
22
20
  gem 'yajl-ruby'
23
21
  end
24
22
 
25
- platforms(:jruby) do
23
+ platforms :rbx do
24
+ gem 'rubysl-weakref' # used in rest-core
25
+ gem 'rubysl-singleton' # used in rake
26
+ gem 'rubysl-rexml' # used in crack used in webmock
27
+ gem 'rubysl-bigdecimal' # used in crack used in webmock
28
+ end
29
+
30
+ platforms :jruby do
26
31
  gem 'jruby-openssl'
27
32
  end
data/NOTE.md CHANGED
@@ -43,6 +43,6 @@ and use that along with pre-built ones to compose a very customized client.
43
43
 
44
44
  We present you rest-core.
45
45
 
46
- [rest-core]: https://github.com/cardinalblue/rest-core
46
+ [rest-core]: https://github.com/godfat/rest-core
47
47
  [Rack]: https://github.com/rack/rack
48
48
  [Faraday]: https://github.com/technoweenie/faraday
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
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
- by Cardinal Blue <http://cardinalblue.com>
3
+ by Lin Jen-Shin ([godfat](http://godfat.org))
4
4
 
5
5
  Lin Jen-Shin ([godfat][]) had given a talk about rest-core on
6
6
  [RubyConf Taiwan 2011][talk]. The slide is in English, but the
@@ -11,9 +11,9 @@ talk is in Mandarin.
11
11
 
12
12
  ## LINKS:
13
13
 
14
- * [github](https://github.com/cardinalblue/rest-core)
14
+ * [github](https://github.com/godfat/rest-core)
15
15
  * [rubygems](https://rubygems.org/gems/rest-core)
16
- * [rdoc](http://rdoc.info/projects/cardinalblue/rest-core)
16
+ * [rdoc](http://rdoc.info/projects/godfat/rest-core)
17
17
  * [mailing list](http://groups.google.com/group/rest-core/topics)
18
18
 
19
19
  ## DESCRIPTION:
@@ -27,28 +27,36 @@ that allows you to build a REST client for any REST API. Or in the case of
27
27
  common APIs such as Facebook, Github, and Twitter, you can simply use the
28
28
  dedicated clients provided by [rest-more][].
29
29
 
30
- [rest-more]: https://github.com/cardinalblue/rest-more
30
+ [rest-more]: https://github.com/godfat/rest-more
31
31
 
32
32
  ## FEATURES:
33
33
 
34
34
  * Modular interface for REST clients similar to WSGI/Rack for servers.
35
35
  * Concurrent requests with synchronous or asynchronous interfaces with
36
- fibers or threads are both supported.
36
+ threads.
37
+
38
+ ## WHY?
39
+
40
+ Build your own API clients for less dependencies, less codes,
41
+ less memory, less conflicts, and run faster.
37
42
 
38
43
  ## REQUIREMENTS:
39
44
 
40
45
  ### Mandatory:
41
46
 
42
- * MRI (official CRuby) 1.9.3, Rubinius 1.9 and JRuby 1.9
43
- * gem rest-client
47
+ * Tested with MRI (official CRuby), Rubinius and JRuby.
48
+ * gem [httpclient][]
49
+ * gem [mime-types][]
50
+ * gem [timers][]
51
+
52
+ [httpclient]: https://github.com/nahi/httpclient
53
+ [mime-types]: https://github.com/halostatue/mime-types
54
+ [timers]: https://github.com/celluloid/timers
44
55
 
45
56
  ### Optional:
46
57
 
47
- * gem [em-http-request][] (if using eventmachine)
48
58
  * gem json or yajl-ruby, or multi_json (if `JsonResponse` or
49
- `JsonRequest` middlewares are used)
50
-
51
- [em-http-request]: https://github.com/igrigorik/em-http-request
59
+ `JsonRequest` middleware is used)
52
60
 
53
61
  ## INSTALLATION:
54
62
 
@@ -59,14 +67,14 @@ gem install rest-core
59
67
  Or if you want development version, put this in Gemfile:
60
68
 
61
69
  ``` ruby
62
- gem 'rest-core', :git => 'git://github.com/cardinalblue/rest-core.git',
70
+ gem 'rest-core', :git => 'git://github.com/godfat/rest-core.git',
63
71
  :submodules => true
64
72
  ```
65
73
 
66
74
  If you just want to use Facebook or Twitter clients, please take a look at
67
75
  [rest-more][] which has a lot of clients built with rest-core.
68
76
 
69
- [rest-more]: http://github.com/cardinalblue/rest-more
77
+ [rest-more]: http://github.com/godfat/rest-more
70
78
 
71
79
  ## Build Your Own Clients:
72
80
 
@@ -90,12 +98,12 @@ configuration, e.g. different cache time or timeout time):
90
98
 
91
99
  ``` ruby
92
100
  client = YourClient.new(:cache => {})
93
- client.get('cardinalblue') # cache miss
94
- client.get('cardinalblue') # cache hit
101
+ client.get('godfat') # cache miss
102
+ client.get('godfat') # cache hit
95
103
 
96
104
  client.site = 'http://github.com/api/v2/json/user/show/'
97
- client.get('cardinalblue') # cache miss
98
- client.get('cardinalblue') # cache hit
105
+ client.get('godfat') # cache miss
106
+ client.get('godfat') # cache hit
99
107
  ```
100
108
 
101
109
  ### Concurrent Requests with Futures:
@@ -104,7 +112,7 @@ You can also make concurrent requests easily:
104
112
  (see "Advanced Concurrent HTTP Requests -- Embrace the Future" for detail)
105
113
 
106
114
  ``` ruby
107
- a = [client.get('cardinalblue'), client.get('godfat')]
115
+ a = [client.get('godfat'), client.get('cardinalblue')]
108
116
  puts "It's not blocking... but doing concurrent requests underneath"
109
117
  p a.map{ |r| r['name'] } # here we want the values, so it blocks here
110
118
  puts "DONE"
@@ -165,7 +173,7 @@ should work.
165
173
  On the other hand, callback mode also available:
166
174
 
167
175
  ``` ruby
168
- client.get('cardinalblue'){ |v| p v }
176
+ client.get('godfat'){ |v| p v }
169
177
  puts "It's not blocking... but doing concurrent requests underneath"
170
178
  client.wait # we block here to wait for the request done
171
179
  puts "DONE"
@@ -191,6 +199,108 @@ client.wait # we block here to wait for the request done
191
199
  puts "DONE"
192
200
  ```
193
201
 
202
+ ### Thread Pool / Connection Pool
203
+
204
+ Underneath, rest-core would spawn a thread for each request, freeing you
205
+ from blocking. However, occasionally we would not want this behaviour,
206
+ giving that we might have limited resource and cannot maximize performance.
207
+
208
+ For example, maybe we could not afford so many threads running concurrently,
209
+ or the target server cannot accept so many concurrent connections. In those
210
+ cases, we would want to have limited concurrent threads or connections.
211
+
212
+ ``` ruby
213
+ YourClient.pool_size = 10
214
+ YourClient.pool_idle_time = 60
215
+ ```
216
+
217
+ This could set the thread pool size to 10, having a maximum of 10 threads
218
+ running together, growing from requests. Each threads idled more than 60
219
+ seconds would be shut down automatically.
220
+
221
+ Note that `pool_size` should at least be larger than 4, or it might be
222
+ very likely to have _deadlock_ if you're using nested callbacks and having
223
+ a large number of concurrent calls.
224
+
225
+ Also, setting `pool_size` to `-1` would mean we want to make blocking
226
+ requests, without spawning any threads. This might be useful for debugging.
227
+
228
+ ### Persistent connections (keep-alive connections)
229
+
230
+ Since we're using [httpclient][] by default now, we would reuse connections,
231
+ making it much faster for hitting the same host repeatedly.
232
+
233
+ ### Streaming Requests
234
+
235
+ Suppose we want to POST a file, instead of trying to read all the contents
236
+ in memory and send them, we could stream it from the file system directly.
237
+
238
+ ``` ruby
239
+ client.post('path', File.open('README.md'))
240
+ ```
241
+
242
+ Basically, payloads could be any IO object. Check out
243
+ [RC::Payload](lib/rest-core/util/payload.rb) for more information.
244
+
245
+ ### Streaming Responses
246
+
247
+ This one is much harder then streaming requests, since all built-in
248
+ middleware actually assume the responses should be blocking and buffered.
249
+ Say, some JSON parser could not really parse from streams.
250
+
251
+ We solve this issue similarly to the way Rack solves it. That is, we hijack
252
+ the socket. This would be how we're doing:
253
+
254
+ ``` ruby
255
+ sock = client.get('path', {}, RC::HIJACK => true)
256
+ p sock.read(10)
257
+ p sock.read(10)
258
+ p sock.read(10)
259
+ ```
260
+
261
+ Of course, if we don't want to block in order to get the socket, we could
262
+ always use the callback form:
263
+
264
+ ``` ruby
265
+ client.get('path', {}, RC::HIJACK => true) do |sock|
266
+ p sock.read(10)
267
+ p sock.read(10)
268
+ p sock.read(10)
269
+ end
270
+ ```
271
+
272
+ Note that since the socket would be put inside `RC::RESPONSE_SOCKET`
273
+ instead of `RC::RESPONSE_BODY`, not all middleware would handle the socket.
274
+ In the case of hijacking, `RC::RESPONSE_BODY` would always be mapped to an
275
+ empty string, as it does not make sense to store the response in this case.
276
+
277
+ ### SSE (Server-Sent Events)
278
+
279
+ Not only JavaScript could receive server-sent events, any languages could.
280
+ Doing so would establish a keep-alive connection to the server, and receive
281
+ data periodically. We'll take Firebase as an example:
282
+
283
+ ``` ruby
284
+ es = RC::Universal.new.event_source(
285
+ 'https://SampleChat.firebaseIO-demo.com/users/tom/.json')
286
+
287
+ es.onopen{ |sock| p "Socket: #{sock}" }
288
+ es.onmessage{ |event| p "Event: #{event}" }
289
+ es.onerror{ |error| p "Error: #{error}" }
290
+
291
+ es.start # Start making the request
292
+ sleep(5) # Sleep awhile to see anything is happening
293
+ es.close # Close the connection when we're done
294
+ ```
295
+
296
+ Those callbacks would be called in a separate background thread,
297
+ so we don't have to worry about blocking it. If we want to wait for
298
+ the connection to be closed, we could call `wait`:
299
+
300
+ ``` ruby
301
+ es.wait # This would block until the connection is closed
302
+ ```
303
+
194
304
  ### More Control with `request_full`:
195
305
 
196
306
  You can also use `request_full` to retrieve everything including response
@@ -202,17 +312,15 @@ including the path.
202
312
  ``` ruby
203
313
  client.request_full({})[RC::RESPONSE_BODY] # {"message"=>"Not Found"}
204
314
  # This would print something like this:
205
- # RestCore: Auto picked: RestCore::RestClient
206
- # RestCore: Future picked: RestCore::Future::FutureThread
207
- # RestCore: spent 1.135713 Requested GET https://api.github.com/users//
315
+ # RestCore: spent 1.135713 Requested GET https://api.github.com/users/
208
316
 
209
- client.request_full(RC::REQUEST_PATH => 'cardinalblue')[RC::RESPONSE_STATUS]
210
- client.request_full(RC::REQUEST_PATH => 'cardinalblue')[RC::RESPONSE_HEADERS]
317
+ client.request_full(RC::REQUEST_PATH => 'godfat')[RC::RESPONSE_STATUS]
318
+ client.request_full(RC::REQUEST_PATH => 'godfat')[RC::RESPONSE_HEADERS]
211
319
  # Headers are normalized with all upper cases and
212
320
  # dashes are replaced by underscores.
213
321
 
214
322
  # To make POST (or any other request methods) request:
215
- client.request_full(RC::REQUEST_PATH => 'cardinalblue',
323
+ client.request_full(RC::REQUEST_PATH => 'godfat',
216
324
  RC::REQUEST_METHOD => :post)[RC::RESPONSE_STATUS] # 404
217
325
  ```
218
326
 
@@ -222,15 +330,15 @@ Runnable example is at: [example/simple.rb][]. Please see [rest-more][]
222
330
  for more complex examples to build clients, and [slides][] from
223
331
  [rubyconf.tw/2011][rubyconf.tw] for concepts.
224
332
 
225
- [example/simple.rb]: https://github.com/cardinalblue/rest-core/blob/master/example/simple.rb
226
- [rest-more]: https://github.com/cardinalblue/rest-more
333
+ [example/simple.rb]: example/simple.rb
334
+ [rest-more]: https://github.com/godfat/rest-more
227
335
  [slides]: http://www.godfat.org/slide/2011-08-27-rest-core.html
228
336
  [rubyconf.tw]: http://rubyconf.tw/2011/#6
229
337
 
230
338
  ## Playing Around:
231
339
 
232
340
  You can also play around with `RC::Universal` client, which has installed
233
- _all_ reasonable middlewares built-in rest-core. So the above example could
341
+ _all_ reasonable middleware built-in rest-core. So the above example could
234
342
  also be achieved by:
235
343
 
236
344
  ``` ruby
@@ -238,7 +346,7 @@ require 'rest-core'
238
346
  client = RC::Universal.new(:site => 'https://api.github.com/users/',
239
347
  :json_response => true,
240
348
  :log_method => method(:puts))
241
- client.get('cardinalblue')
349
+ client.get('godfat')
242
350
  ```
243
351
 
244
352
  `RC::Universal` is defined as:
@@ -276,7 +384,7 @@ rib rest-core
276
384
  And you will be entering a rib shell, which `self` is an instance of
277
385
  `RC::Universal` you can play:
278
386
 
279
- rest-core>> get 'https://api.github.com/users/cardinalblue'
387
+ rest-core>> get 'https://api.github.com/users/godfat'
280
388
 
281
389
  will print out the response from Github. You can also do this to make
282
390
  calling Github easier:
@@ -286,36 +394,56 @@ calling Github easier:
286
394
 
287
395
  Then it would do exactly like the original example:
288
396
 
289
- rest-core>> get 'cardinalblue' # you get a nice parsed hash
397
+ rest-core>> get 'godfat' # you get a nice parsed hash
290
398
 
291
399
  This is mostly for fun and experimenting, so it's only included in
292
400
  [rest-more][] and [rib][]. Please make sure you have both of them
293
401
  installed before trying this.
294
402
 
295
403
  [rib]: https://github.com/godfat/rib
296
- [rest-more]: https://github.com/cardinalblue/rest-more
404
+ [rest-more]: https://github.com/godfat/rest-more
297
405
 
298
406
  ## List of built-in Middleware:
299
407
 
300
- * `RC::AuthBasic`
301
- * `RC::Bypass`
302
- * `RC::Cache`
303
- * `RC::CommonLogger`
304
- * `RC::DefaultHeaders`
305
- * `RC::DefaultPayload`
306
- * `RC::DefaultQuery`
307
- * `RC::DefaultSite`
308
- * `RC::Defaults`
309
- * `RC::ErrorDetector`
310
- * `RC::ErrorDetectorHttp`
311
- * `RC::ErrorHandler`
312
- * `RC::FollowRedirect`
313
- * `RC::JsonRequest`
314
- * `RC::JsonResponse`
315
- * `RC::Oauth1Header`
316
- * `RC::Oauth2Header`
317
- * `RC::Oauth2Query`
318
- * `RC::Timeout`
408
+ * [RC::AuthBasic][]
409
+ * [RC::Bypass][]
410
+ * [RC::Cache][]
411
+ * [RC::CommonLogger][]
412
+ * [RC::DefaultHeaders][]
413
+ * [RC::DefaultPayload][]
414
+ * [RC::DefaultQuery][]
415
+ * [RC::DefaultSite][]
416
+ * [RC::Defaults][]
417
+ * [RC::ErrorDetector][]
418
+ * [RC::ErrorDetectorHttp][]
419
+ * [RC::ErrorHandler][]
420
+ * [RC::FollowRedirect][]
421
+ * [RC::JsonRequest][]
422
+ * [RC::JsonResponse][]
423
+ * [RC::Oauth1Header][]
424
+ * [RC::Oauth2Header][]
425
+ * [RC::Oauth2Query][]
426
+ * [RC::Timeout][]
427
+
428
+ [RC::AuthBasic]: lib/rest-core/middleware/auth_basic.rb
429
+ [RC::Bypass]: lib/rest-core/middleware/bypass.rb
430
+ [RC::Cache]: lib/rest-core/middleware/cache.rb
431
+ [RC::CommonLogger]: lib/rest-core/middleware/common_logger.rb
432
+ [RC::DefaultHeaders]: lib/rest-core/middleware/default_headers.rb
433
+ [RC::DefaultPayload]: lib/rest-core/middleware/default_payload.rb
434
+ [RC::DefaultQuery]: lib/rest-core/middleware/default_query.rb
435
+ [RC::DefaultSite]: lib/rest-core/middleware/default_site.rb
436
+ [RC::Defaults]: lib/rest-core/middleware/defaults.rb
437
+ [RC::ErrorDetector]: lib/rest-core/middleware/error_detector.rb
438
+ [RC::ErrorDetectorHttp]: lib/rest-core/middleware/error_detector_http.rb
439
+ [RC::ErrorHandler]: lib/rest-core/middleware/error_handler.rb
440
+ [RC::FollowRedirect]: lib/rest-core/middleware/follow_redirect.rb
441
+ [RC::JsonRequest]: lib/rest-core/middleware/json_request.rb
442
+ [RC::JsonResponse]: lib/rest-core/middleware/json_response.rb
443
+ [RC::Oauth1Header]: lib/rest-core/middleware/oauth1_header.rb
444
+ [RC::Oauth2Header]: lib/rest-core/middleware/oauth2_header.rb
445
+ [RC::Oauth2Query]: lib/rest-core/middleware/oauth2_query.rb
446
+ [RC::Timeout]: lib/rest-core/middleware/timeout.rb
319
447
 
320
448
  ## Build Your Own Middleware:
321
449
 
@@ -425,8 +553,8 @@ YourClient = RC::Builder.client do
425
553
  end
426
554
 
427
555
  client = YourClient.new
428
- puts "rest-client with threads doing concurrent requests"
429
- a = [client.get('cardinalblue'), client.get('godfat')]
556
+ puts "httpclient with threads doing concurrent requests"
557
+ a = [client.get('godfat'), client.get('cardinalblue')]
430
558
  puts "It's not blocking... but doing concurrent requests underneath"
431
559
  p a.map{ |r| r['name'] } # here we want the values, so it blocks here
432
560
  puts "DONE"
@@ -443,11 +571,11 @@ YourClient = RC::Builder.client do
443
571
  end
444
572
 
445
573
  client = YourClient.new
446
- puts "rest-client with threads doing concurrent requests"
447
- client.get('cardinalblue'){ |v|
574
+ puts "httpclient with threads doing concurrent requests"
575
+ client.get('godfat'){ |v|
448
576
  p v['name']
449
577
  }.
450
- get('godfat'){ |v|
578
+ get('cardinalblue'){ |v|
451
579
  p v['name']
452
580
  }
453
581
  puts "It's not blocking... but doing concurrent requests underneath"
@@ -459,85 +587,21 @@ You can pick whatever works for you.
459
587
 
460
588
  [future]: http://en.wikipedia.org/wiki/Futures_and_promises
461
589
 
462
- ### What Concurrency Model to Choose?
463
-
464
- In the above example, we're using rest-client with threads, which works
465
- for most of cases. But you might also want to use em-http-request with
466
- EventMachine, which is using a faster HTTP parser. In theory, it should
467
- be much more efficient than rest-client and threads.
468
-
469
- To pick em-http-request, you must run the requests inside the EventMachine's
470
- event loop, and also wrap your request with either a thread or a fiber,
471
- because we can't block the event loop and ask em-http-request to finish
472
- its job making requests.
473
-
474
- Here's an example of using em-http-request with threads:
475
-
476
- ``` ruby
477
- require 'em-http-request'
478
- require 'rest-core'
479
- YourClient = RC::Builder.client do
480
- use RC::DefaultSite , 'https://api.github.com/users/'
481
- use RC::JsonResponse, true
482
- use RC::CommonLogger, method(:puts)
483
- end
484
-
485
- client = YourClient.new
486
- puts "eventmachine with threads doing concurrent requests"
487
- EM.run{
488
- Thread.new{
489
- a = [client.get('cardinalblue'), client.get('godfat')]
490
- p a.map{ |r| r['name'] } # here we want the values, so it blocks here
491
- puts "DONE"
492
- EM.stop
493
- }
494
- puts "It's not blocking... but doing concurrent requests underneath"
495
- }
496
- ```
497
-
498
- And here's an example of using em-http-request with fibers:
499
-
500
- ``` ruby
501
- require 'fiber' # remember to require fiber first,
502
- require 'em-http-request' # or rest-core won't pick fibers
503
- require 'rest-core'
504
- YourClient = RC::Builder.client do
505
- use RC::DefaultSite , 'https://api.github.com/users/'
506
- use RC::JsonResponse, true
507
- use RC::CommonLogger, method(:puts)
508
- end
509
-
510
- client = YourClient.new
511
- puts "eventmachine with fibers doing concurrent requests"
512
- EM.run{
513
- Fiber.new{
514
- a = [client.get('cardinalblue'), client.get('godfat')]
515
- p a.map{ |r| r['name'] } # here we want the values, so it blocks here
516
- puts "DONE"
517
- EM.stop
518
- }
519
- puts "It's not blocking... but doing concurrent requests underneath"
520
- }
521
- ```
522
-
523
- As you can see, both of them are quite similar to each other, because the
524
- idea behind the scene is the same. If you don't know what concurrency model
525
- to pick, start with rest-client since it's the easiest one to setup.
526
-
527
- A full runnable example is at: [example/multi.rb][]. If you want to know
590
+ A full runnable example is at: [example/simple.rb][]. If you want to know
528
591
  all the possible use cases, you can also see: [example/use-cases.rb][]. It's
529
592
  also served as a test for each possible combinations, so it's quite complex
530
593
  and complete.
531
594
 
532
- [example/multi.rb]: https://github.com/cardinalblue/rest-core/blob/master/example/multi.rb
533
-
534
- [example/use-cases.rb]: https://github.com/cardinalblue/rest-core/blob/master/example/use-cases.rb
595
+ [example/simple.rb]: example/simple.rb
596
+ [example/use-cases.rb]: example/use-cases.rb
535
597
 
536
598
  ## rest-core users:
537
599
 
538
- * [topcoder](https://github.com/miaout17/topcoder)
600
+ * [rest-more][]
601
+ * [rest-more-yahoo_buy](https://github.com/GoodLife/rest-more-yahoo_buy)
539
602
  * [s2sync](https://github.com/brucehsu/s2sync)
540
603
  * [s2sync_web](https://github.com/brucehsu/s2sync_web)
604
+ * [topcoder](https://github.com/miaout17/topcoder)
541
605
 
542
606
  ## Powered sites:
543
607
 
@@ -545,7 +609,7 @@ and complete.
545
609
 
546
610
  ## CHANGES:
547
611
 
548
- * [CHANGES](https://github.com/cardinalblue/rest-core/blob/master/CHANGES.md)
612
+ * [CHANGES](CHANGES.md)
549
613
 
550
614
  ## CONTRIBUTORS:
551
615
 
@@ -557,7 +621,9 @@ and complete.
557
621
  * Florent Vaucelle (@florent)
558
622
  * Jaime Cham (@jcham)
559
623
  * John Fan (@johnfan)
624
+ * khoa nguyen (@khoan)
560
625
  * Lin Jen-Shin (@godfat)
626
+ * lulalala (@lulalala)
561
627
  * Mariusz Pruszynski (@snicky)
562
628
  * Mr. Big Cat (@miaout17)
563
629
  * Nicolas Fouché (@nfo)
@@ -567,7 +633,7 @@ and complete.
567
633
 
568
634
  Apache License 2.0
569
635
 
570
- Copyright (c) 2011-2012, Cardinal Blue
636
+ Copyright (c) 2011-2014, Lin Jen-Shin (godfat)
571
637
 
572
638
  Licensed under the Apache License, Version 2.0 (the "License");
573
639
  you may not use this file except in compliance with the License.