frenetic 0.0.1.alpha1 → 0.0.1

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/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