frenetic 0.0.1.alpha1 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -5,108 +5,6 @@
5
5
 
6
6
  An opinionated Ruby-based Hypermedia API (HAL+JSON) client.
7
7
 
8
- ## About
9
-
10
- fre&bull;net&bull;ic |frəˈnetik|<br/>
11
- adjective<br/>
12
- fast and energetic in a rather wild and uncontrolled way : *a frenetic pace of activity.*
13
-
14
- So basically, this is a crazy way to interact with your Hypermedia HAL+JSON API.
15
-
16
- Get it? *Hypermedia*?
17
-
18
- *Hyper*?
19
-
20
- ...
21
-
22
- If you have not implemented a HAL+JSON API, then this will not work very well for you.
23
-
24
- ## Opinions
25
-
26
- Like I said, it is opinionated. It is so opinionated, it is probably the biggest
27
- a-hole you've ever met.
28
-
29
- Maybe in time, if you teach it, it will become more open-minded.
30
-
31
- ### HAL+JSON Content Type
32
-
33
- Frenetic expects all responses to be in [HAL+JSON][hal_json]. It chose that
34
- standard because it is trying to make JSON API's respond in a predictable
35
- manner, which it thinks is an awesome idea.
36
-
37
- ### Authentication
38
-
39
- Frenetic is going to try and use Basic Auth whether you like it or not. If
40
- that is not required, nothing will probably happen. But its going to send the
41
- header anyway.
42
-
43
- ### API Description
44
-
45
- The API's root URL must respond with a description, much like the
46
- [Spire.io][spire.io] API. This is crucial in order for Frenetic to work. If
47
- Frenetic doesn't know what the API contains, it can't parse any resource
48
- responses.
49
-
50
- It is expected that any subclasses of `Frenetic::Resource` will adhere to the
51
- schema defined here.
52
-
53
- Example:
54
-
55
- ```js
56
- {
57
- "_links":{
58
- "self":{"href":"/api/"},
59
- "inkers":{"href":"/api/inkers"},
60
- },
61
- "_embedded":{
62
- "schema":{
63
- "_links":{
64
- "self":{"href":"/api/schema"}
65
- },
66
- "order":{
67
- "description":"A widget order",
68
- "type":"object",
69
- "properties":{
70
- "id":{"type":"integer"},
71
- "first_name":{"type":"string"},
72
- "last_name":{"type":"string"},
73
- }
74
- }
75
- }
76
- }
77
- }
78
- ```
79
-
80
- This response will be requested by Frenetic whenever a call to
81
- `YourAPI.description` is made. The response is memoized so any future calls
82
- will not trigger another API request.
83
-
84
- ### API Resources
85
-
86
- While HAL+JSON is awesome, not all implementations are perfect. Frenetic
87
- assumes a HAL+JSON response as built by [Roar], which may not be in 100%
88
- compliance.
89
-
90
- Example:
91
-
92
- ```js
93
- {
94
- "id":1,
95
- "first_name":"Foo",
96
- "last_name":"Bar",
97
- "_links":{
98
- "self":{"href":"/order/1"},
99
- "next":{"href":"/order/2"}
100
- }
101
- }
102
- ```
103
-
104
- The problem here is that the entire response really should be wrapped in
105
- `"_embedded"` and `"order"` keys.
106
-
107
- So until that is fixed, Frenetic will continue to be pig headed and continue
108
- to do the "wrong" thing.
109
-
110
8
  ## Installation
111
9
 
112
10
  Add this line to your application's Gemfile:
@@ -123,91 +21,7 @@ Or install it yourself as:
123
21
 
124
22
  ## Usage
125
23
 
126
- ### Client Initialization
127
-
128
- ```ruby
129
- MyAPI = Frenetic.new(
130
- 'url' => 'https://api.yoursite.com',
131
- 'username' => 'yourname',
132
- 'password' => 'yourpassword',
133
- 'headers' => {
134
- 'accept' => 'application/vnd.yoursite-v1.hal+json'
135
- # Optional
136
- 'user-agent' => 'Your Site's API Client', # Optional custom User Agent, just 'cuz
137
- }
138
- )
139
- ```
140
-
141
- ### Making Requests
142
-
143
- Once you have created a client instance, you are free to use it however you'd
144
- like.
145
-
146
- A Frenetic instance supports any HTTP verb that [Faraday][faraday] has
147
- impletented. This includes GET, POST, PUT, PATCH, and DELETE.
148
-
149
- #### Frenetic::Resource
150
-
151
- An easier way to make requests for a resource is to have your model inherit from
152
- `Frenetic::Resource`. This makes it a bit easier to encapsulate all of your
153
- resource's API requests into one place.
154
-
155
- ```ruby
156
- class Order < Frenetic::Resource
157
-
158
- api_client { MyAPI }
159
-
160
- class << self
161
- def find( id )
162
- if response = api.get( api.description.links.order.href.gsub('{id}', id.to_s) ) and response.success?
163
- self.new( response.body )
164
- else
165
- raise OrderNotFound, "No Order found for #{id}"
166
- end
167
- end
168
- end
169
- end
170
- ```
171
-
172
- The `api_client` class method merely tells `Frenetic::Resource` which API Client
173
- instance to use. If you lazily instantiate your client, then you should pass a
174
- block as demonstrated above.
175
-
176
- Otherwise, you may pass by reference:
177
-
178
- ```ruby
179
- class Order < Frenetic::Resource
180
- api_client MyAPI
181
- end
182
- ```
183
-
184
- When your model is initialized, it will contain attribute readers for every
185
- property defined in your API's schema or description. In theory, this allows an
186
- API to add, remove, or change properties without the need to directly update
187
- your model.
188
-
189
- ### Interpretting Responses
190
-
191
- Any response body returned by a Frenetic generated API call will be returned as
192
- an OpenStruct-like object. This object responds to dot-notation as well as Hash
193
- keys and is enumerable.
194
-
195
- ```ruby
196
- response.body.resources.orders.first
197
- ```
198
-
199
- or
200
-
201
- ```ruby
202
- response.body['_embedded']['orders'][0]
203
- ```
204
-
205
- For your convenience, certain HAL+JSON keys have been aliased by methods a bit
206
- more readable:
207
-
208
- * `_embedded` can be referenced as `resources`
209
- * `_links` can be referenced as `links`
210
- * `href` can be referenced as `url`
24
+ Your guess is as good as mine. (*TODO*)
211
25
 
212
26
  ## Contributing
213
27
 
@@ -216,8 +30,3 @@ more readable:
216
30
  3. Commit your changes (`git commit -am 'Added some feature'`)
217
31
  4. Push to the branch (`git push origin my-new-feature`)
218
32
  5. Create new Pull Request
219
-
220
- [hal_json]: http://stateless.co/hal_specification.html
221
- [spire.io]: http://api.spire.io/
222
- [roar]: https://github.com/apotonick/roar
223
- [faraday]: https://github.com/technoweenie/faraday
@@ -1,5 +1,4 @@
1
1
  require 'addressable/uri'
2
- require 'patron' # Needed to prevent https://github.com/technoweenie/faraday/issues/140
3
2
  require 'faraday'
4
3
 
5
4
  require "frenetic/configuration"
@@ -15,7 +15,11 @@ class Frenetic
15
15
  config[:headers] ||= {}
16
16
  config[:request] ||= {}
17
17
 
18
- config[:headers][:accept] ||= "application/hal+json"
18
+ if config[:"content-type"]
19
+ config[:headers][:accepts] = config[:"content-type"]
20
+ else
21
+ config[:headers][:accepts] = "application/hal+json"
22
+ end
19
23
 
20
24
  # Copy the config into this Configuration instance.
21
25
  config.each { |k, v| self[k] = v }
@@ -1,3 +1,3 @@
1
1
  class Frenetic
2
- VERSION = "0.0.1.alpha1"
2
+ VERSION = "0.0.1"
3
3
  end
@@ -4,9 +4,7 @@ describe Frenetic::Configuration do
4
4
  { 'test' => {
5
5
  'url' => 'http://example.org',
6
6
  'api_key' => '1234567890',
7
- 'headers' => {
8
- 'accept' => content_type,
9
- },
7
+ 'content-type' => content_type,
10
8
  'request' => {
11
9
  'timeout' => 10000
12
10
  }
@@ -39,16 +37,16 @@ describe Frenetic::Configuration do
39
37
  subject[:headers][:user_agent].should =~ %r{Frenetic v.+; \S+$}
40
38
  end
41
39
 
42
- context "with a specified Accept header" do
43
- it "should set an Accept request header" do
44
- subject[:headers].should include(:accept => 'application/vnd.frenetic-v1-hal+json')
40
+ context "with a specified Content-Type" do
41
+ it "should set an Accepts request header" do
42
+ subject[:headers].should include(:accepts => 'application/vnd.frenetic-v1-hal+json')
45
43
  end
46
44
  end
47
- context "without a specified Accept header" do
45
+ context "without a specified Content-Type" do
48
46
  let(:content_type) { nil }
49
47
 
50
- it "should set an Accept request header" do
51
- subject[:headers].should include(:accept => 'application/hal+json')
48
+ it "should set an Accepts request header" do
49
+ subject[:headers].should include(:accepts => 'application/hal+json')
52
50
  end
53
51
  end
54
52
  end
@@ -65,7 +63,7 @@ describe Frenetic::Configuration do
65
63
  it { should be_a( Hash ) }
66
64
  it { should_not be_empty }
67
65
  it "should set an Accepts request header" do
68
- subject[:headers].should include(:accept => 'application/hal+json')
66
+ subject[:headers].should include(:accepts => 'application/hal+json')
69
67
  end
70
68
  it "should set a User Agent request header" do
71
69
  subject[:headers][:user_agent].should =~ %r{Frenetic v.+; \S+$}
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: frenetic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.alpha1
5
- prerelease: 6
4
+ version: 0.0.1
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Derek Lindahl
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-16 00:00:00.000000000Z
12
+ date: 2012-04-11 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
16
- requirement: &2156831400 !ruby/object:Gem::Requirement
16
+ requirement: &2157361220 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.8.0.rc2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2156831400
24
+ version_requirements: *2157361220
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: addressable
27
- requirement: &2156830640 !ruby/object:Gem::Requirement
27
+ requirement: &2157360720 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.2.7
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2156830640
35
+ version_requirements: *2157360720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: patron
38
- requirement: &2156829960 !ruby/object:Gem::Requirement
38
+ requirement: &2157360240 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.4.18
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2156829960
46
+ version_requirements: *2157360240
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: guard-spork
49
- requirement: &2156829240 !ruby/object:Gem::Requirement
49
+ requirement: &2157359780 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.6.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2156829240
57
+ version_requirements: *2157359780
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: guard-rspec
60
- requirement: &2156828580 !ruby/object:Gem::Requirement
60
+ requirement: &2157359320 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.7.0
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2156828580
68
+ version_requirements: *2157359320
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &2156827880 !ruby/object:Gem::Requirement
71
+ requirement: &2157358860 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 2.9.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2156827880
79
+ version_requirements: *2157358860
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: bourne
82
- requirement: &2156827200 !ruby/object:Gem::Requirement
82
+ requirement: &2157358400 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 1.1.2
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *2156827200
90
+ version_requirements: *2157358400
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: webmock
93
- requirement: &2156826480 !ruby/object:Gem::Requirement
93
+ requirement: &2157357940 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: 1.8.6
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *2156826480
101
+ version_requirements: *2157357940
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: vcr
104
- requirement: &2156825880 !ruby/object:Gem::Requirement
104
+ requirement: &2157357480 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: 2.0.1
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *2156825880
112
+ version_requirements: *2157357480
113
113
  description: An opinionated Ruby-based Hypermedia API client.
114
114
  email:
115
115
  - dlindahl@customink.com
@@ -155,9 +155,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
155
155
  required_rubygems_version: !ruby/object:Gem::Requirement
156
156
  none: false
157
157
  requirements:
158
- - - ! '>'
158
+ - - ! '>='
159
159
  - !ruby/object:Gem::Version
160
- version: 1.3.1
160
+ version: '0'
161
161
  requirements: []
162
162
  rubyforge_project:
163
163
  rubygems_version: 1.8.10