README.md in rest-more-1.0.2 vs README.md in rest-more-2.0.0

- old
+ new

@@ -4,12 +4,10 @@ Lin Jen-Shin ([godfat][]) had given a talk about rest-core on [RubyConf Taiwan 2011][talk]. The slide is in English, but the talk is in Mandarin. -You can also read some other topics at [doc](https://github.com/cardinalblue/rest-core/blob/master/doc/ToC.md). - [godfat]: https://github.com/godfat [talk]: http://rubyconf.tw/2011/#6 ## LINKS: @@ -26,201 +24,117 @@ ## FEATURES: Out-of-box REST clients built with rest-core for: -* Bing * Dropbox * Facebook * Github * Linkedin -* Mixi * Twitter Rails utilities are also included. ## REQUIREMENTS: ### Mandatory: -* MRI (official CRuby) 1.8.7, 1.9.2, 1.9.3, Rubinius 1.8/1.9 and JRuby 1.8/1.9 +* MRI (official CRuby) 1.9.3, Rubinius 1.9 and JRuby 1.9 +* gem rest-core * gem rest-client ### Optional: -* Fibers only work on Ruby 1.9+ * gem [em-http-request][] (if using eventmachine) -* gem [cool.io-http][] (if using cool.io) -* gem json or yajl-ruby (if using `JsonDecode` middleware) +* gem json or yajl-ruby, or multi_json (if `JsonResponse` or + `JsonRequest` middlewares are used) [em-http-request]: https://github.com/igrigorik/em-http-request -[cool.io-http]: https://github.com/godfat/cool.io-http ## INSTALLATION: ``` shell - gem install rest-more +gem install rest-more ``` Or if you want development version, put this in Gemfile: ``` ruby - gem 'rest-more', :git => 'git://github.com/cardinalblue/rest-more.git', - :submodules => true +gem 'rest-more', :git => 'git://github.com/cardinalblue/rest-more.git', + :submodules => true ``` ## SYNOPSIS: The simplest usage: ``` ruby - require 'rest-more' +require 'rest-more' - RestCore::Twitter.new.statuses('_cardinalblue') # get user tweets - RestCore::Github.new.get('users/cardinalblue') # get user info +RC::Twitter.new.statuses('_cardinalblue') # get user tweets +RC::Github.new.get('users/cardinalblue') # get user info - linkedin = RestCore::Linkedin.new(:consumer_key => '...', - :consumer_secret => '...') - linkedin.authorize_url! # copy and paste the URL in browser to authorize - linkedin.authorize!('..') # paste your code from browser - linkedin.me # get current user info +linkedin = RC::Linkedin.new(:consumer_key => '...', + :consumer_secret => '...') +linkedin.authorize_url! # copy and paste the URL in browser to authorize +linkedin.authorize!('..') # paste your code from browser +linkedin.me # get current user info - RestCore::Facebook.new.get('4') # get user info +RC::Facebook.new.get('4') # get user info ``` -Runnable example is here: [example/simple.rb][]. Please see [slides][] from +Runnable example is at: [example/simple.rb][]. Please see [slides][] from [rubyconf.tw/2011][rubyconf.tw] for concepts. [example/simple.rb]: https://github.com/cardinalblue/rest-more/blob/master/example/simple.rb [slides]: http://www.godfat.org/slide/2011-08-27-rest-core.html [rubyconf.tw]: http://rubyconf.tw/2011/#6 -## Asynchronous HTTP Requests: +## Concurrent HTTP Requests: -I/O bound operations shouldn't be blocking the CPU! If you have a reactor, -i.e. event loop, you should take the advantage of that to make HTTP requests -not block the whole process/thread. For now, we support eventmachine and -cool.io. By default, all clients are using `RestClient`, which is a -synchronous HTTP client, thus blocking. It's very easy to use, but not -very scalable (not concurrent-efficient). You can change the default app -(i.e. HTTP clients) to an asynchronous one: +Inherited from rest-core, you can do concurrent requests quite easily. +Here's a very quick example of getting Facebook users' names for UID 4 and 5: ``` ruby - require 'rest-more' - RestCore::Builder.default_app = RestCore::EmHttpRequest +require 'rest-more' +facebook = RC::Facebook.new(:log_method => method(:puts)) +puts "rest-client with threads doing concurrent requests" +a = [facebook.get('4'), facebook.get('5')] +puts "It's not blocking... but doing concurrent requests underneath" +p a.map{ |r| r['name'] } # here we want the values, so it blocks here +puts "DONE" ``` -or an auto-picking one, which would try to infer the correct HTTP client -depending on the context. Either em-http-request, cool.io-http, or even -rest-client if none of reactors is available. +If you prefer callback based solution, this would also work: ``` ruby - require 'rest-more' - RestCore::Builder.default_app = RestCore::Auto +require 'rest-more' +facebook = RC::Facebook.new(:log_method => method(:puts)) +puts "callback also works" +facebook.get('6'){ |r| + p r['name'] +} +puts "It's not blocking... but doing concurrent requests underneath" +facebook.wait # we block here to wait for the request done +puts "DONE" ``` -You can also setup the `default_app` for a specific client, so that it won't -change all the `default_app` for all the clients, like this: +Runnable example is at: [example/multi.rb][]. For a detailed demonstration, +see: [Advanced Concurrent HTTP Requests -- Embrace the Future][future] -``` ruby - require 'rest-more' - RestCore::Facebook.builder.default_app = RestCore::Auto -``` - -If you're passing a block, the block is called after the response is -available. That is the block is the callback for the request. - -``` ruby - require 'rest-more' - require 'eventmachine' - RestCore::Builder.default_app = RestCore::EmHttpRequest - EM.run{ - RestCore::Facebook.new.get('4'){ |response| - p response - EM.stop - } - puts "It's not blocking..." - } -``` - -Otherwise, if you don't pass a block as the callback, EmHttpRequest (i.e. -the HTTP client for eventmachine) would call `Fiber.yield` to yield to the -original fiber, making asynchronous HTTP requests look like synchronous. -If you don't understand what does this mean, you can take a look at -[em-synchrony][]. It's basically the same idea. - -``` ruby - require 'rest-more' - require 'eventmachine' - - RestCore::Builder.default_app = RestCore::EmHttpRequest - - EM.run{ - Fiber.new{ - p RestCore::Facebook.new.get('4') - EM.stop - }.resume - puts "It's not blocking..." - } -``` - -[em-synchrony]: https://github.com/igrigorik/em-synchrony - -Runnable example is here: [example/facebook.rb][]. -You can also make multi-requests synchronously like this: - -``` ruby - require 'rest-more' - require 'eventmachine' - - RestCore::Builder.default_app = RestCore::Auto - facebook = RestCore::Facebook.new(:log_method => method(:puts)) - - EM.run{ - Fiber.new{ - fiber = Fiber.current - result = {} - facebook.get('4'){ |response| - result[0] = response - fiber.resume(result) if result.size == 2 - } - puts "It's not blocking..." - facebook.get('4'){ |response| - result[1] = response - fiber.resume(result) if result.size == 2 - } - p Fiber.yield - EM.stop - }.resume - puts "It's not blocking..." - } -``` - -Runnable example is here: [example/multi.rb][]. All `RestCore::EmHttpRequest` -above is interchangeable with `RestCore::Auto` because `RestCore::Auto` would -pick the right HTTP client when running inside the eventmachine's event loop. - -[example/facebook.rb]: https://github.com/cardinalblue/rest-more/blob/master/example/facebook.rb [example/multi.rb]: https://github.com/cardinalblue/rest-more/blob/master/example/multi.rb +[future]: https://github.com/cardinalblue/rest-core#advanced-concurrent-http-requests----embrace-the-future -## Supported HTTP clients: - -* `RestCore::RestClient` (gem rest-client) -* `RestCore::EmHttpRequest` (gem em-http-request) -* `RestCore::Coolio` (gem cool.io) -* `RestCore::Auto` (which would pick one of the above depending on the - context) - ## Rails Utilities -To be added. But you can take a look at the [Facebook tutorial][] first. +To be added. But you can take a look at [Facebook tutorial][] first. [Facebook tutorial]: https://github.com/cardinalblue/rest-more/blob/master/doc/tutorial/facebook.md ## EventMachine inside Rainbows! -To be added. But you can take a look at the [Rainbows configuration][] first. +To be added. But you can take a look at [Rainbows configuration][] first. [Rainbows configuration]: https://github.com/cardinalblue/rest-more/blob/master/example/rainbows.rb ## A simple interactive shell with [rib][]: @@ -229,10 +143,10 @@ gem install rib Then you can try this by running `rib rest-core`: rest-core>> self.site = 'https://api.github.com/users/' - rest-core>> self.json_decode = true + rest-core>> self.json_response = true rest-core>> get 'cardinalblue' Which is using `RestCore::Universal` for accessing arbitrary websites. [rib]: https://github.com/godfat/rib