Skip to content

Commit af7de24

Browse files
committed
Omit navigational elements of a HAL response.
1 parent ecaf3a6 commit af7de24

File tree

15 files changed

+348
-208
lines changed

15 files changed

+348
-208
lines changed

.rubocop_todo.yml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This configuration was generated by `rubocop --auto-gen-config`
2-
# on 2014-09-17 21:23:50 -0400 using RuboCop version 0.26.0.
2+
# on 2014-09-18 12:21:47 -0400 using RuboCop version 0.26.0.
33
# The point is for the user to remove these configuration records
44
# one by one as the offenses are removed from the code base.
55
# Note that changes in the inspected code, or installation of new
@@ -8,28 +8,36 @@
88
# Offense count: 1
99
# Configuration parameters: CountComments.
1010
Metrics/ClassLength:
11-
Max: 106
11+
Max: 118
1212

13-
# Offense count: 36
13+
# Offense count: 2
14+
Metrics/CyclomaticComplexity:
15+
Max: 8
16+
17+
# Offense count: 39
1418
# Configuration parameters: AllowURI.
1519
Metrics/LineLength:
16-
Max: 140
20+
Max: 145
1721

1822
# Offense count: 1
1923
# Configuration parameters: CountComments.
2024
Metrics/MethodLength:
2125
Max: 14
2226

27+
# Offense count: 2
28+
Metrics/PerceivedComplexity:
29+
Max: 9
30+
2331
# Offense count: 1
2432
Style/AsciiComments:
2533
Enabled: false
2634

27-
# Offense count: 3
35+
# Offense count: 2
2836
# Configuration parameters: EnforcedStyle, SupportedStyles.
2937
Style/ClassAndModuleChildren:
3038
Enabled: false
3139

32-
# Offense count: 15
40+
# Offense count: 14
3341
Style/Documentation:
3442
Enabled: false
3543

@@ -41,7 +49,7 @@ Style/DoubleNegation:
4149
Style/Lambda:
4250
Enabled: false
4351

44-
# Offense count: 6
52+
# Offense count: 5
4553
# Configuration parameters: MaxSlashes.
4654
Style/RegexpLiteral:
4755
Enabled: false

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
== Next
2+
3+
* backwards incompatible changes
4+
* All navigational structure methods, including `links`, `get` or `post`, have been renamed to `_link`, `_get`, or `_post` respectively (by @dblock).
5+
26
* enhancements
37
* [#58](https://github.com/codegram/hyperclient/issues/58): Automatically follow redirects (by [@dblock](https://github.com/dblock)).
8+
* [#63](https://github.com/codegram/hyperclient/pull/63): You can omit the navigational elements, `api.links.products` is now equivalent to `api.products` (by @dblock).
9+
* Implemented Rubocop, Ruby-style linter (by @dblock).
10+
11+
* bug fixes
12+
* Nothing.
13+
14+
* deprecations
15+
* Nothing.
416

517
== 0.3.1
18+
619
* backwards incompatible changes
720
* Nothing.
821

Readme.md renamed to README.md

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ Example API client:
1616
```ruby
1717
api = Hyperclient.new('http://myapp.com/api').tap do |api|
1818
api.digest_auth('user', 'password')
19-
api.headers.update({'accept-encoding' => 'deflate, gzip'})
19+
api.headers.update('accept-encoding' => 'deflate, gzip')
2020
end
2121
```
2222

23-
By default, Hyperclient adds `application/json` as `Content-Type` and `Accept`
24-
headers. It will also sent requests as JSON and parse JSON responses.
23+
By default, Hyperclient adds `application/json` as `Content-Type` and `Accept` headers. It will also sent requests as JSON and parse JSON responses.
2524

2625
[More examples][examples]
2726

@@ -38,15 +37,22 @@ Hyperclient will try to fetch and discover the resources from your API.
3837
Accessing the links for a given resource is quite straightforward:
3938

4039
```ruby
41-
api.links.posts_categories
40+
api._links.posts_categories
41+
# => #<Resource ...>
42+
```
43+
44+
Or omit `_links`, which will look for a link called "posts_categories" by default:
45+
46+
```ruby
47+
api.posts_categories
4248
# => #<Resource ...>
4349
```
4450

4551
You can also iterate between all the links:
4652

4753
```ruby
48-
api.links.each do |name, link|
49-
puts name, link.url
54+
api._links.each do |name, link|
55+
puts name, link._url
5056
end
5157
```
5258

@@ -55,15 +61,21 @@ Actually, you can call any [Enumerable][enumerable] method :D
5561
If a Resource doesn't have friendly name you can always access it as a Hash:
5662

5763
```ruby
58-
api.links['http://myapi.org/rels/post_categories']
64+
api._links['http://myapi.org/rels/post_categories']
5965
```
6066

6167
### Embedded resources
6268

6369
Accessing embedded resources is similar to accessing links:
6470

6571
```ruby
66-
api.embedded.posts
72+
api._embedded.posts
73+
```
74+
75+
Or omit the `_embedded` keyword. By default Hyperclient will look for a "posts" link, then for an embedded "posts" collection:
76+
77+
```ruby
78+
api.posts
6779
```
6880

6981
And you can also iterate between them:
@@ -80,10 +92,25 @@ You can even chain different calls (this also applies for links):
8092
api.embedded.posts.first.links.author
8193
```
8294

95+
Or omit the navigational structures:
96+
97+
```ruby
98+
api.posts.first.author
99+
```
100+
101+
If you have a named link that retrieves an embedded collection of the same name, you can collapse the nested reference. The following statements produce identical results:
102+
103+
```ruby
104+
api.links.posts.embedded.posts.first
105+
```
106+
107+
```ruby
108+
api.posts.first
109+
```
110+
83111
### Attributes
84112

85-
Not only you might have links and embedded resources in a Resource, but also
86-
its attributes:
113+
Not only you might have links and embedded resources in a Resource, but also its attributes:
87114

88115
```ruby
89116
api.embedded.posts.first.attributes
@@ -95,6 +122,9 @@ api.embedded.posts.first.attributes
95122
You can access the attribute values via attribute methods, or as a hash:
96123

97124
```ruby
125+
api.posts.first.title
126+
# => 'Linting the hell out of your Ruby classes with Pelusa'
127+
98128
api.embedded.posts.first.attributes.title
99129
# => 'Linting the hell out of your Ruby classes with Pelusa'
100130

@@ -107,35 +137,38 @@ api.embedded.posts.first.attributes.fetch('title')
107137

108138
### HTTP
109139

110-
OK, navigating an API is really cool, but you may want to actually do something
111-
with it, right?
140+
OK, navigating an API is really cool, but you may want to actually do something with it, right?
112141

113-
Hyperclient uses [Faraday][faraday] under the hood to perform HTTP calls. You can
114-
call any valid HTTP method on any Resource:
142+
Hyperclient uses [Faraday][faraday] under the hood to perform HTTP calls. You can call any valid HTTP method on any Resource:
115143

116144
```ruby
117-
post = api.embedded.posts.first
118-
post.get
119-
post.head
120-
post.put({title: 'New title'})
121-
post.patch({title: 'New title'})
122-
post.delete
123-
post.options
124-
125-
posts = api.links.posts
126-
posts.post({title: "I'm a blogger!", body: 'Wohoo!!'})
145+
post = api._embedded.posts.first
146+
post._get
147+
post._head
148+
post._put(title: 'New title')
149+
post._patch(title: 'New title')
150+
post._delete
151+
post._options
152+
153+
posts = api._links.posts
154+
posts._post(title: "I'm a blogger!", body: 'Wohoo!!')
127155
```
128156

129157
If you have a templated link you can expand it like so:
130158

131159
```ruby
132-
api.links.post.expand(:id => 3).first
160+
api._links.post._expand(id: 3).first
161+
# => #<Resource ...>
162+
```
163+
164+
You can omit the "_expand" keyword.
165+
166+
```ruby
167+
api.post(id: 3).first
133168
# => #<Resource ...>
134169
```
135170

136-
You can access the Faraday connection (to add middlewares or do whatever
137-
you want) by calling `connection` on the entry point. As an example, you could use the [faraday-http-cache-middleware](https://github.com/plataformatec/faraday-http-cache)
138-
:
171+
You can access the Faraday connection (to add middlewares or do whatever you want) by calling `connection` on the entry point. As an example, you could use the [faraday-http-cache-middleware](https://github.com/plataformatec/faraday-http-cache):
139172

140173
```ruby
141174
api.connection.use :http_cache
@@ -168,7 +201,7 @@ There's also a PHP library named [HyperClient](https://github.com/FoxyCart/Hyper
168201

169202
## License
170203

171-
MIT License. Copyright 2012 [Codegram Technologies][codegram]
204+
MIT License. Copyright 2012-2014 [Codegram Technologies][codegram]
172205

173206
[hal]: http://stateless.co/hal_specification.html
174207
[contributors]: https://github.com/codegram/hyperclient/contributors

examples/cyberscore.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def print_links(links)
4444
if link.is_a?(Array)
4545
print_links(link)
4646
else
47-
puts %(Found "#{name}" at "#{link.url}" )
47+
puts %(Found "#{name}" at "#{link._url}" )
4848
end
4949
end
5050
end

examples/hal_shop.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
def print_resources(resources)
55
resources.each do |name, resource|
66
begin
7-
puts %(Found #{name} at #{resource.url})
7+
puts %(Found #{name} at #{resource._url})
88
rescue
99
puts %(Found #{name})
1010
end

features/steps/api_navigation.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,32 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
22
include API
33

44
step 'I should be able to navigate to posts and authors' do
5-
api.links.posts.resource
6-
api.links['api:authors'].resource
5+
api._links.posts._resource
6+
api._links['api:authors']._resource
77

88
assert_requested :get, 'http://api.example.org/posts'
99
assert_requested :get, 'http://api.example.org/authors'
1010
end
1111

1212
step 'I search for a post with a templated link' do
13-
api.links.search.expand(q: 'something').resource
13+
api._links.search._expand(q: 'something')._resource
1414
end
1515

1616
step 'the API should receive the request with all the params' do
1717
assert_requested :get, 'http://api.example.org/search?q=something'
1818
end
1919

2020
step 'I load a single post' do
21-
@post = api.links.posts.links.last_post
21+
@post = api._links.posts._links.last_post
2222
end
2323

2424
step 'I should be able to access it\'s title and body' do
25-
@post.attributes.title.wont_equal nil
26-
@post.attributes.body.wont_equal nil
25+
@post._attributes.title.wont_equal nil
26+
@post._attributes.body.wont_equal nil
2727
end
2828

2929
step 'I should also be able to access it\'s embedded comments' do
30-
comment = @post.embedded.comments.first
31-
comment.attributes.title.wont_equal nil
30+
comment = @post._embedded.comments.first
31+
comment._attributes.title.wont_equal nil
3232
end
3333
end

features/steps/default_config.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ class Spinach::Features::DefaultConfig < Spinach::FeatureSteps
1111

1212
step 'I send some data to the API' do
1313
stub_request(:post, 'http://api.example.org/posts')
14-
assert_equal 200, api.links.posts.post(title: 'My first blog post').status
14+
assert_equal 200, api._links.posts._post(title: 'My first blog post').status
1515
end
1616

1717
step 'it should have been encoded as JSON' do
1818
assert_requested :post, 'api.example.org/posts', body: '{"title":"My first blog post"}'
1919
end
2020

2121
step 'I get some data from the API' do
22-
@posts = api.links.posts
22+
@posts = api._links.posts
2323
end
2424

2525
step 'it should have been parsed as JSON' do
26-
@posts.attributes.total_posts.to_i.must_equal 9
27-
@posts.attributes['total_posts'].to_i.must_equal 9
26+
@posts._attributes.total_posts.to_i.must_equal 9
27+
@posts._attributes['total_posts'].to_i.must_equal 9
2828
end
2929
end

features/support/api.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def api
1515
end
1616

1717
step 'I connect to the API' do
18-
api.links
18+
api._links
1919
end
2020

2121
after do

lib/hyperclient/entry_point.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def initialize(url)
2727
#
2828
# Returns a Faraday::Connection.
2929
def connection
30-
@connection ||= Faraday.new(url, { headers: default_headers }, &default_faraday_block)
30+
@connection ||= Faraday.new(_url, { headers: default_headers }, &default_faraday_block)
3131
end
3232

3333
private

0 commit comments

Comments
 (0)