weary 0.7.2 → 1.0.0.rc1
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/.gitignore +4 -1
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/Gemfile +11 -8
- data/Gemfile.lock +49 -53
- data/LICENSE +1 -1
- data/README.md +134 -208
- data/Rakefile +6 -47
- data/lib/weary.rb +4 -66
- data/lib/weary/adapter.rb +23 -0
- data/lib/weary/adapters/net_http.rb +68 -0
- data/lib/weary/client.rb +243 -0
- data/lib/weary/deferred.rb +35 -0
- data/lib/weary/env.rb +32 -0
- data/lib/weary/middleware.rb +9 -0
- data/lib/weary/middleware/basic_auth.rb +17 -0
- data/lib/weary/middleware/content_type.rb +28 -0
- data/lib/weary/middleware/oauth.rb +31 -0
- data/lib/weary/request.rb +137 -124
- data/lib/weary/resource.rb +152 -128
- data/lib/weary/response.rb +48 -99
- data/lib/weary/route.rb +53 -0
- data/lib/weary/version.rb +3 -0
- data/spec/spec_helper.rb +4 -56
- data/spec/support/shared_examples_for_a_rack_app.rb +70 -0
- data/spec/support/shared_examples_for_a_rack_env.rb +14 -0
- data/spec/support/shared_examples_for_a_uri.rb +9 -0
- data/spec/weary/adapter_spec.rb +26 -0
- data/spec/weary/adapters/nethttp_spec.rb +88 -0
- data/spec/weary/client_spec.rb +258 -0
- data/spec/weary/deferred_spec.rb +35 -0
- data/spec/weary/env_spec.rb +12 -0
- data/spec/weary/middleware/basic_auth_spec.rb +23 -0
- data/spec/weary/middleware/content_type_spec.rb +34 -0
- data/spec/weary/middleware/oauth_spec.rb +27 -0
- data/spec/weary/request_spec.rb +227 -315
- data/spec/weary/resource_spec.rb +233 -233
- data/spec/weary/response_spec.rb +82 -159
- data/spec/weary/route_spec.rb +72 -0
- data/spec/weary_spec.rb +3 -56
- data/weary.gemspec +16 -79
- metadata +138 -98
- data/VERSION +0 -1
- data/examples/batch.rb +0 -20
- data/examples/repo.rb +0 -16
- data/examples/status.rb +0 -26
- data/lib/weary/base.rb +0 -124
- data/lib/weary/batch.rb +0 -37
- data/lib/weary/exceptions.rb +0 -15
- data/lib/weary/httpverb.rb +0 -32
- data/spec/fixtures/github.yml +0 -11
- data/spec/fixtures/twitter.xml +0 -763
- data/spec/fixtures/vimeo.json +0 -1
- data/spec/weary/base_spec.rb +0 -320
- data/spec/weary/batch_spec.rb +0 -71
- data/spec/weary/httpverb_spec.rb +0 -25
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
source
|
1
|
+
source "http://rubygems.org"
|
2
2
|
|
3
|
-
|
4
|
-
gem 'oauth', '>= 0.3.5'
|
3
|
+
gemspec
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
gem "rake", "~> 0.9.2"
|
6
|
+
|
7
|
+
group :doc do
|
8
|
+
gem "yard", "~> 0.7.5"
|
9
|
+
gem "yard-tomdoc", "~> 0.4.0"
|
10
|
+
end
|
11
|
+
|
12
|
+
platforms :jruby do
|
13
|
+
gem "jruby-openssl"
|
11
14
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,53 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
-
|
26
|
-
|
27
|
-
|
28
|
-
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
hash: 840ef225827ef421653168c75a110d1a0a2e39a9
|
51
|
-
sources:
|
52
|
-
- Rubygems:
|
53
|
-
uri: http://gemcutter.org
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
weary (1.0.0.rc1)
|
5
|
+
addressable (~> 2.2.6)
|
6
|
+
multi_json (~> 1.1.0)
|
7
|
+
promise (~> 0.3.0)
|
8
|
+
rack (~> 1.4.0)
|
9
|
+
simple_oauth (~> 0.1.5)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: http://rubygems.org/
|
13
|
+
specs:
|
14
|
+
addressable (2.2.6)
|
15
|
+
crack (0.3.1)
|
16
|
+
diff-lcs (1.1.3)
|
17
|
+
multi_json (1.1.0)
|
18
|
+
promise (0.3.0)
|
19
|
+
rack (1.4.1)
|
20
|
+
rake (0.9.2.2)
|
21
|
+
rspec (2.8.0)
|
22
|
+
rspec-core (~> 2.8.0)
|
23
|
+
rspec-expectations (~> 2.8.0)
|
24
|
+
rspec-mocks (~> 2.8.0)
|
25
|
+
rspec-core (2.8.0)
|
26
|
+
rspec-expectations (2.8.0)
|
27
|
+
diff-lcs (~> 1.1.2)
|
28
|
+
rspec-mocks (2.8.0)
|
29
|
+
simple_oauth (0.1.5)
|
30
|
+
tomparse (0.2.0)
|
31
|
+
webmock (1.7.10)
|
32
|
+
addressable (~> 2.2, > 2.2.5)
|
33
|
+
crack (>= 0.1.7)
|
34
|
+
yard (0.7.5)
|
35
|
+
yard-tomdoc (0.4.0)
|
36
|
+
tomparse
|
37
|
+
yard
|
38
|
+
|
39
|
+
PLATFORMS
|
40
|
+
ruby
|
41
|
+
|
42
|
+
DEPENDENCIES
|
43
|
+
jruby-openssl
|
44
|
+
rake (~> 0.9.2)
|
45
|
+
rspec (~> 2.8.0)
|
46
|
+
weary!
|
47
|
+
webmock (~> 1.7.10)
|
48
|
+
yard (~> 0.7.5)
|
49
|
+
yard-tomdoc (~> 0.4.0)
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,218 +1,144 @@
|
|
1
1
|
# Weary
|
2
2
|
|
3
|
-
|
3
|
+
_Weary is a framework and DSL for building clients for (preferably RESTful) web service APIs._
|
4
4
|
|
5
|
-
|
5
|
+
At its most minimal, Weary is simply some nice syntactic sugar around Net/HTTP.
|
6
6
|
|
7
|
-
|
8
|
-
+ Parse XML and JSON with the [Crack](http://github.com/jnunemaker/crack) library.
|
9
|
-
+ Authentication with Basic Authentication and [OAuth](http://oauth.net/).
|
10
|
-
+ Asynchronous, multi-threaded requests.
|
7
|
+
If you dig a bit deeper, it's a suite of tools built around the [Rack](http://rack.rubyforge.org/) ecosystem. As you build a client, remember that just about every class in Weary is a piece of Rack middleware or a Rack application underneath the covers.
|
11
8
|
|
12
|
-
|
9
|
+
It features:
|
13
10
|
|
14
|
-
|
11
|
+
* Full Rack integration:
|
15
12
|
|
16
|
-
|
17
|
-
+ [OAuth](http://github.com/mojodna/oauth) >= 0.3.5
|
13
|
+
There are points in the stack to hook in Rack middleware and just about every class in Weary is a Rack application in its own right.
|
18
14
|
|
19
|
-
|
15
|
+
* Asynchronous:
|
16
|
+
|
17
|
+
`Weary::Request#perform`, the thing that performs the request, returns a [future](http://en.wikipedia.org/wiki/Futures_and_promises) and only blocks when accessed.
|
18
|
+
|
19
|
+
It takes its inspiration from [HTTParty](https://github.com/jnunemaker/httparty) and [Faraday](https://github.com/technoweenie/faraday).
|
20
20
|
|
21
|
-
gem install weary
|
22
|
-
|
23
|
-
If you're interested in doing development on Weary, clone the repository and run `bundle install` to get the development dependencies.
|
24
|
-
|
25
21
|
## Quick Start
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
That will build the Get request to fetch the YAML info about this repository.
|
150
|
-
|
151
|
-
Pass a block to `Weary.get` to dive further into the Request:
|
152
|
-
|
153
|
-
Weary.get "http://twitter.com/statuses/user_timeline" do |req|
|
154
|
-
req.follows = false
|
155
|
-
req.with = {:id => 'markwunsch'}
|
156
|
-
req.credentials = {:username => 'markwunsch', :password => 'secret'}
|
157
|
-
req.headers = {"User-Agent" => Weary::UserAgents["Safari 4.0.2 - Mac"]}
|
158
|
-
end
|
159
|
-
|
160
|
-
## Request Callbacks
|
161
|
-
|
162
|
-
A `Weary::Request` has a couple of callbacks you can do:
|
163
|
-
|
164
|
-
status = Weary.get("http://twitter.com/statuses/user_timeline") do |r|
|
165
|
-
r.with = {:id => 'markwunsch'}
|
166
|
-
end
|
167
|
-
|
168
|
-
status.before_send do |request|
|
169
|
-
puts "Sending a request to #{request.uri}"
|
170
|
-
end
|
171
|
-
|
172
|
-
status.on_complete do |response|
|
173
|
-
if response.success?
|
174
|
-
puts response.body
|
175
|
-
else
|
176
|
-
puts "Something went wrong: #{response.code}: #{response.message}"
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
`before_send` is sent just before the request is made, and `on_complete` is triggered immediately following. `before_send` passes the Request object to the block and `on_complete` passes the Response object.
|
181
|
-
|
182
|
-
You don't need to define `on_complete`, though. Passing a block to the `perform` method of the Request also defines this callback or will overwrite what you had previously defined:
|
183
|
-
|
184
|
-
status.perform do |response|
|
185
|
-
puts "Request to #{response.url}, complete. Got a #{response.code}."
|
186
|
-
end
|
187
|
-
|
188
|
-
## Multiple Asynchronous Requests with Batch
|
189
|
-
|
190
|
-
Requests, along with the `perform` method, also has a `perform!` method, which spins off a Thread to actually perform the Net::HTTP Request. This method returns a Thread object, and is encapsulated by the `perform` method.
|
191
|
-
|
192
|
-
Weary::Batch allows you to make a group of `perform!` requests, firing at will. It takes a group of Requests.
|
193
|
-
|
194
|
-
# see examples/batch.rb
|
195
|
-
resources = %w[http://twitter.com http://github.com http://vimeo.com http://tumblr.com]
|
196
|
-
requests = []
|
197
|
-
|
198
|
-
## build the group of requests:
|
199
|
-
resources.each do |url|
|
200
|
-
requests << Weary.get(url) do |req|
|
201
|
-
req.on_complete {|res| puts "Hello from #{res.url}"}
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
## And fire them off:
|
206
|
-
Weary.batch(requests).perform
|
207
|
-
|
208
|
-
Batch has callbacks, just like the Request:
|
209
|
-
|
210
|
-
Weary.batch(requests).perform do
|
211
|
-
puts 'All done.'
|
212
|
-
end
|
213
|
-
|
214
|
-
You can investigate the pool of threads once you've called `perform` with `Batch#pool` or look at all the returned responses with `Batch#responses`.
|
215
|
-
|
216
|
-
## And more...
|
217
|
-
|
218
|
-
There's more to discover in the Wiki.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
# http://developer.github.com/v3/repos/
|
25
|
+
class GithubRepo < Weary::Client
|
26
|
+
domain "https://api.github.com"
|
27
|
+
|
28
|
+
use Rack::Lint
|
29
|
+
|
30
|
+
get :list_user_repos, "/users/{user}/repos" do |resource|
|
31
|
+
resource.optional :type
|
32
|
+
end
|
33
|
+
|
34
|
+
get :get, "/repos/{user}/{repo}"
|
35
|
+
end
|
36
|
+
|
37
|
+
client = GithubRepo.new
|
38
|
+
client.list_user_repos(:user => "mwunsch").perform do |response|
|
39
|
+
puts response.body if response.success?
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
This is a basic example of a client you will build using the Weary framework. If you're coming from a previous version of Weary, you would have created a subclass of `Weary::Base`. That's one of the many changes in the **big rewrite**.
|
44
|
+
|
45
|
+
### Weary::Client
|
46
|
+
|
47
|
+
Inherit from `Weary::Client` for a set of class methods that craft "Resources" (more on that later).
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
MyClass < Weary::Client
|
51
|
+
get :resource, "http://host.com/path/to/resource" do |resource|
|
52
|
+
resource.optional :optional_parameter
|
53
|
+
end
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
The DSL provides methods for all of the HTTP verbs (See `Weary::Client::REQUEST_METHODS`). When you instantiate this class, the object will have an instance method named "resource" that will return a `Weary::Request` object set up to perform a "GET" request on "http://host.com/path/to/resource".
|
58
|
+
|
59
|
+
You can pass a block these methods for access to the `Weary::Resource`.
|
60
|
+
|
61
|
+
Further methods in the DSL include:
|
62
|
+
|
63
|
+
domain - This will be prepended to every path when resources are defined
|
64
|
+
(Particularly useful when using Client's Rack integration, discussed below).
|
65
|
+
optional - See Resource section below.
|
66
|
+
required - See Resource section below.
|
67
|
+
defaults - See Resource section below.
|
68
|
+
headers - See Resource section below.
|
69
|
+
use - A Rack::Middleware to place in the Request stack.
|
70
|
+
(See Rack integration further down)
|
71
|
+
|
72
|
+
|
73
|
+
#### Weary::Resource
|
74
|
+
|
75
|
+
The resource is a building block used in `Client` to describe the requirements of a request.
|
76
|
+
|
77
|
+
optional - A group of keys for parameters that the request expects.
|
78
|
+
required - Keys that the request needs in order to be performed.
|
79
|
+
defaults - Default parameters to be sent in every request.
|
80
|
+
headers - Headers to send in the request.
|
81
|
+
user_agent - A convenience method to set the User Agent header.
|
82
|
+
basic_auth! - Prepare the request to accept a username and password for basic authentication.
|
83
|
+
oauth! - Prepare the request to accept the consumer key and access token in the request.
|
84
|
+
|
85
|
+
Finally, the `request` method of the Resource takes a set of parameters to verify that requirements are met and returns a `Weary::Request` object. It should all look something like this once all is said and done.
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
# https://dev.twitter.com/docs/api/1/post/statuses/update
|
89
|
+
post :update, "http://api.twitter.com/1/statuses/update.json" do |resource|
|
90
|
+
resource.required :status
|
91
|
+
resource.optional :in_reply_to_status_id, :lat, :long, :place_id,
|
92
|
+
:display_coordinates, :trim_user, :include_entities
|
93
|
+
resource.oauth!
|
94
|
+
end
|
95
|
+
|
96
|
+
# After instantiating the client:
|
97
|
+
# (This calls the "update" resource's `request` method)
|
98
|
+
client.update :status => "I'm tweeting from Weary",
|
99
|
+
:consumer_key => "an_oauth_consumer_key",
|
100
|
+
:token => "my_oauth_access_token"
|
101
|
+
|
102
|
+
```
|
103
|
+
|
104
|
+
If a `required` parameter is missing, a `Weary::Resource::UnmetRequirementsError` exception is raised.
|
105
|
+
|
106
|
+
URL's for these methods can also be dynamic. If we alter the above example:
|
107
|
+
|
108
|
+
post :update, "http://api.twitter.com/1/statuses/update.{format}" do |resource|
|
109
|
+
|
110
|
+
Then a key `:format` will be expected to be passed with the other parameters.
|
111
|
+
|
112
|
+
The method that the Client defines (in the above example, the `client.update` method), can take an optional block that allows you to manipulate the underlying `Weary::Request` object.
|
113
|
+
|
114
|
+
### Weary::Request
|
115
|
+
|
116
|
+
No matter how you get there, you'll end up with a Weary::Request object. Call the `perform` method to actually make the request and get back a `Weary::Response`. That's not entirely true `Weary::Request#perform` is asynchronous and non-blocking. It returns a future and will only block once you call a method on the response. You can optionally pass a block that's executed once the response has returned.
|
117
|
+
|
118
|
+
By default, the request is performed through [Net::HTTP](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html). This is done through `Weary::Adapter::NetHttp`. A `Weary::Adapter` is just a special kind of Rack application. `Request#adapter` allows you to hook up your own.
|
119
|
+
|
120
|
+
## Rack
|
121
|
+
|
122
|
+
To maximize the utility of Weary, it's important to remember that driving everything is Rack. Almost every class is built to provide a Rack interface.
|
123
|
+
|
124
|
+
Every class that inherits from `Weary::Client` is a Rack application.
|
125
|
+
|
126
|
+
A `Weary::Request` is a Rack application. When you call `Request#call` it creates its own special Rack environment. In order to preserve your Rack middleware, you can add your middleware to the stack using `Request#use`.
|
127
|
+
|
128
|
+
When using `Weary::Client` the `use` method will add the passed middleware to every Request stack.
|
129
|
+
|
130
|
+
Authentication, by default is done by either `Weary::Middleware::BasicAuth` or `Weary::Middleware::OAuth`. Both are just Rack middleware, and can be used in any Rack stack.
|
131
|
+
|
132
|
+
The point is, **it's just Rack**.
|
133
|
+
|
134
|
+
## Release Candidate
|
135
|
+
|
136
|
+
At this point, I need _your_ help to further Weary along. I'd love to see more examples that utilize the Rackness of Weary: using Devise, Warden, or mounted in a Rails application.
|
137
|
+
|
138
|
+
## Examples
|
139
|
+
|
140
|
+
[**Gilt**](https://github.com/mwunsch/gilt) is a Ruby client to the [Gilt public API](https://dev.gilt.com/). Notice how much of the code is dedicated to the Gilt domain model, and very little to actually interacting with the web service. That's the idea.
|
141
|
+
|
142
|
+
## Copyright
|
143
|
+
|
144
|
+
Copyright (c) 2009 - 2012 Mark Wunsch. Licensed under the [MIT License](http://opensource.org/licenses/mit-license.php).
|