Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 556 lines (421 sloc) 14.409 kb
b32ba65 Rémi Prévost Update travis badge to display the master branch status
authored
1 # Her [![Build Status](https://secure.travis-ci.org/remiprev/her.png?branch=master)](http://travis-ci.org/remiprev/her) [![Gem dependency status](https://gemnasium.com/remiprev/her.png?travis)](https://gemnasium.com/remiprev/her)
871ef96 Rémi Prévost Add README
authored
2
6bd587d Rémi Prévost Improve README, yay!
authored
3 Her is an ORM (Object Relational Mapper) that maps REST resources to Ruby objects. It is designed to build applications that are powered by a RESTful API instead of a database.
871ef96 Rémi Prévost Add README
authored
4
5 ## Installation
6
7 In your Gemfile, add:
8
60f209e Rémi Prévost Update README
authored
9 ```ruby
10 gem "her"
11 ```
871ef96 Rémi Prévost Add README
authored
12
6878101 Rémi Prévost Update documentation with new API code
authored
13 That’s it!
14
d907ddd Rémi Prévost Bump version to 0.2.4, add note about UPGRADE.md
authored
15 ## Upgrade
16
17 Please see the [UPGRADE.md](https://github.com/remiprev/her/blob/master/UPGRADE.md) file for backward compability issues.
18
871ef96 Rémi Prévost Add README
authored
19 ## Usage
20
53744d4 Rémi Prévost Do not set any default middleware
authored
21 First, you have to define which API your models will be bound to. For example, with Rails, you would create a new `config/initializers/her.rb` file with these lines:
871ef96 Rémi Prévost Add README
authored
22
23 ```ruby
cdeb59f Rémi Prévost Add Multiple APIs section in README
authored
24 # config/initializers/her.rb
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
25 Her::API.setup :url => "https://api.example.com" do |connection|
26 connection.use Faraday::Request::UrlEncoded
27 connection.use Her::Middleware::DefaultParseJSON
28 connection.use Faraday::Adapter::NetHttp
53744d4 Rémi Prévost Do not set any default middleware
authored
29 end
871ef96 Rémi Prévost Add README
authored
30 ```
31
6878101 Rémi Prévost Update documentation with new API code
authored
32 And then to add the ORM behavior to a class, you just have to include `Her::Model` in it:
871ef96 Rémi Prévost Add README
authored
33
34 ```ruby
35 class User
36 include Her::Model
37 end
38 ```
39
40 After that, using Her is very similar to many ActiveModel-like ORMs:
41
42 ```ruby
a6e9967 Rémi Prévost Update README with more examples
authored
43 User.all
cdeb59f Rémi Prévost Add Multiple APIs section in README
authored
44 # GET https://api.example.com/users and return an array of User objects
a6e9967 Rémi Prévost Update README with more examples
authored
45
46 User.find(1)
cdeb59f Rémi Prévost Add Multiple APIs section in README
authored
47 # GET https://api.example.com/users/1 and return a User object
a6e9967 Rémi Prévost Update README with more examples
authored
48
49 @user = User.create(:fullname => "Tobias Fünke")
bc5779a Rémi Prévost Fix typo
authored
50 # POST "https://api.example.com/users" with the data and return a User object
a6e9967 Rémi Prévost Update README with more examples
authored
51
52 @user = User.new(:fullname => "Tobias Fünke")
53 @user.occupation = "actor"
54 @user.save
cdeb59f Rémi Prévost Add Multiple APIs section in README
authored
55 # POST https://api.example.com/users with the data and return a User object
a6e9967 Rémi Prévost Update README with more examples
authored
56
57 @user = User.find(1)
58 @user.fullname = "Lindsay Fünke"
59 @user.save
cdeb59f Rémi Prévost Add Multiple APIs section in README
authored
60 # PUT https://api.example.com/users/1 with the data and return+update the User object
871ef96 Rémi Prévost Add README
authored
61 ```
60f209e Rémi Prévost Update README
authored
62
ca1a516 Rémi Prévost Update example applications
authored
63 You can look into the `examples` directory for sample applications using Her.
64
fd7dbca Rémi Prévost Fix typo in README
authored
65 ## Middleware
3b3c7ac Rémi Prévost Improve middleware handling on API#setup
authored
66
761a014 Rémi Prévost Update leftover “bulder”
authored
67 Since Her relies on [Faraday](https://github.com/technoweenie/faraday) to send HTTP requests, you can choose the middleware used to handle requests and responses. Using the block in the `setup` call, you have access to Faraday’s `connection` object and are able to customize the middleware stack used on each request and response.
3b3c7ac Rémi Prévost Improve middleware handling on API#setup
authored
68
69 ### Authentication
70
761a014 Rémi Prévost Update leftover “bulder”
authored
71 Her doesn’t support authentication by default. However, it’s easy to implement one with request middleware. Using the `connection` block, we can add it to the middleware stack.
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
72
73 For example, to add a API token header to your requests, you would do something like this:
3b3c7ac Rémi Prévost Improve middleware handling on API#setup
authored
74
75 ```ruby
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
76 class TokenAuthentication < Faraday::Middleware
6bd587d Rémi Prévost Improve README, yay!
authored
77 def initialize(app, options={})
78 @options = options
79 end
80
3b3c7ac Rémi Prévost Improve middleware handling on API#setup
authored
81 def call(env)
6bd587d Rémi Prévost Improve README, yay!
authored
82 env[:request_headers]["X-API-Token"] = @options[:token] if @options.include?(:token)
388826c Rémi Prévost Add OAuth example in documentation
authored
83 @app.call(env)
3b3c7ac Rémi Prévost Improve middleware handling on API#setup
authored
84 end
85 end
86
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
87 Her::API.setup :url => "https://api.example.com" do |connection|
6bd587d Rémi Prévost Improve README, yay!
authored
88 # This token could be stored in the client session
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
89 connection.use TokenAuthentication, :token => "bb2b2dd75413d32c1ac421d39e95b978d1819ff611f68fc2fdd5c8b9c7331192"
53744d4 Rémi Prévost Do not set any default middleware
authored
90
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
91 connection.use Faraday::Request::UrlEncoded
92 connection.use Her::Middleware::DefaultParseJSON
93 connection.use Faraday::Adapter::NetHttp
b73abec Rémi Prévost Improve the way we handle middleware; expose Faraday’s connection builde...
authored
94 end
3b3c7ac Rémi Prévost Improve middleware handling on API#setup
authored
95 ```
96
97 Now, each HTTP request made by Her will have the `X-API-Token` header.
98
1154d56 Rémi Prévost Expect first-level data to be returned by APIs
authored
99 ### Parsing JSON data
ab31348 Rémi Prévost Add Parsing data section in README
authored
100
1154d56 Rémi Prévost Expect first-level data to be returned by APIs
authored
101 By default, Her handles JSON data. It expects the resource/collection data to be returned at the first level.
102
8f55b37 Rémi Prévost Fix typo in README
authored
103 ```javascript
ab31348 Rémi Prévost Add Parsing data section in README
authored
104 // The response of GET /users/1
1154d56 Rémi Prévost Expect first-level data to be returned by APIs
authored
105 { "id" : 1, "name" : "Tobias Fünke" }
ab31348 Rémi Prévost Add Parsing data section in README
authored
106
107 // The response of GET /users
1154d56 Rémi Prévost Expect first-level data to be returned by APIs
authored
108 [{ "id" : 1, "name" : "Tobias Fünke" }]
ab31348 Rémi Prévost Add Parsing data section in README
authored
109 ```
110
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
111 However, you can define your own parsing method using a response middleware. The middleware should set `env[:body]` to a hash with three keys: `data`, `errors` and `metadata`. The following code uses a custom middleware to parse the JSON data:
ab31348 Rémi Prévost Add Parsing data section in README
authored
112
113 ```ruby
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
114 # Expects responses like:
115 #
116 # {
117 # "result": {
118 # "id": 1,
119 # "name": "Tobias Fünke"
120 # },
121 # "errors" => []
122 # }
123 #
3d1da8d Rémi Prévost Add support for custom Faraday middleware
authored
124 class MyCustomParser < Faraday::Response::Middleware
125 def on_complete(env)
490c313 Rémi Prévost Fix typo in README
authored
126 json = MultiJson.load(env[:body], :symbolize_keys => true)
1154d56 Rémi Prévost Expect first-level data to be returned by APIs
authored
127 env[:body] = {
6bd587d Rémi Prévost Improve README, yay!
authored
128 :data => json[:result],
1154d56 Rémi Prévost Expect first-level data to be returned by APIs
authored
129 :errors => json[:errors],
130 :metadata => json[:metadata]
131 }
3d1da8d Rémi Prévost Add support for custom Faraday middleware
authored
132 end
133 end
8a5bee6 Rémi Prévost Fix a few typos
authored
134
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
135 Her::API.setup :url => "https://api.example.com" do |connection|
136 connection.use Faraday::Request::UrlEncoded
137 connection.use MyCustomParser
138 connection.use Faraday::Adapter::NetHttp
b73abec Rémi Prévost Improve the way we handle middleware; expose Faraday’s connection builde...
authored
139 end
ab31348 Rémi Prévost Add Parsing data section in README
authored
140 ```
141
388826c Rémi Prévost Add OAuth example in documentation
authored
142 ### OAuth
143
144 Using the `faraday_middleware` and `simple_oauth` gems, it’s fairly easy to use OAuth authentication with Her.
145
146 In your Gemfile:
147
148 ```ruby
c01ceda Rémi Prévost Update OAuth example in README
authored
149 gem "her"
150 gem "faraday_middleware"
151 gem "simple_oauth"
388826c Rémi Prévost Add OAuth example in documentation
authored
152 ```
153
154 In your Ruby code:
155
156 ```ruby
c01ceda Rémi Prévost Update OAuth example in README
authored
157 # Create an application on `https://dev.twitter.com/apps` to set these values
388826c Rémi Prévost Add OAuth example in documentation
authored
158 TWITTER_CREDENTIALS = {
159 :consumer_key => "",
160 :consumer_secret => "",
161 :token => "",
162 :token_secret => ""
163 }
164
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
165 Her::API.setup :url => "https://api.twitter.com/1/" do |connection|
166 connection.use FaradayMiddleware::OAuth, TWITTER_CREDENTIALS
167 connection.use Faraday::Request::UrlEncoded
168 connection.use Her::Middleware::DefaultParseJSON
169 connection.use Faraday::Adapter::NetHttp
b73abec Rémi Prévost Improve the way we handle middleware; expose Faraday’s connection builde...
authored
170 end
388826c Rémi Prévost Add OAuth example in documentation
authored
171
172 class Tweet
173 include Her::Model
174 end
175
176 @tweets = Tweet.get("/statuses/home_timeline.json")
177 ```
178
b73abec Rémi Prévost Improve the way we handle middleware; expose Faraday’s connection builde...
authored
179 ### Caching
180
181 Again, using the `faraday_middleware` makes it very easy to cache requests and responses:
182
183 In your Gemfile:
184
185 ```ruby
186 gem "her"
187 gem "faraday_middleware"
188 ```
189
190 In your Ruby code:
191
192 ```ruby
721b7f4 Rémi Prévost Update caching example in README
authored
193 class MyCache < Hash
194 def read(key)
195 if cached = self[key]
196 Marshal.load(cached)
197 end
4b824f9 Rémi Prévost Update caching example in README
authored
198 end
199
721b7f4 Rémi Prévost Update caching example in README
authored
200 def write(key, data)
201 self[key] = Marshal.dump(data)
4b824f9 Rémi Prévost Update caching example in README
authored
202 end
203
721b7f4 Rémi Prévost Update caching example in README
authored
204 def fetch(key)
205 read(key) || yield.tap { |data| write(key, data) }
4b824f9 Rémi Prévost Update caching example in README
authored
206 end
b73abec Rémi Prévost Improve the way we handle middleware; expose Faraday’s connection builde...
authored
207 end
208
27a9a78 Rémi Prévost Fix typo in README
authored
209 # A cache system must respond to `#write`, `#read` and `#fetch`.
210 # We should be probably using something like Memcached here, not a global object
b73abec Rémi Prévost Improve the way we handle middleware; expose Faraday’s connection builde...
authored
211 $cache = MyCache.new
212
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
213 Her::API.setup :url => "https://api.example.com" do |connection|
214 connection.use Faraday::Request::UrlEncoded
215 connection.use FaradayMiddleware::Caching, $cache
216 connection.use Her::Middleware::DefaultParseJSON
217 connection.use Faraday::Adapter::NetHttp
b73abec Rémi Prévost Improve the way we handle middleware; expose Faraday’s connection builde...
authored
218 end
219
220 class User
221 include Her::Model
222 end
223
224 @user = User.find(1)
6bd587d Rémi Prévost Improve README, yay!
authored
225 # GET /users/1
226
227 @user = User.find(1)
228 # This request will be fetched from the cache
b73abec Rémi Prévost Improve the way we handle middleware; expose Faraday’s connection builde...
authored
229 ```
230
6878101 Rémi Prévost Update documentation with new API code
authored
231 ## Relationships
232
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
233 You can define `has_many`, `has_one` and `belongs_to` relationships in your models. The relationship data is handled in two different ways.
313c487 Rémi Prévost Add better documentation for relationships
authored
234
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
235 1. If Her finds relationship data when parsing a resource, that data will be used to create the associated model objects on the resource.
236 2. If no relationship data was included when parsing a resource, calling a method with the same name as the relationship will fetch the data (providing there’s an HTTP request available for it in the API).
313c487 Rémi Prévost Add better documentation for relationships
authored
237
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
238 For example:
313c487 Rémi Prévost Add better documentation for relationships
authored
239
6878101 Rémi Prévost Update documentation with new API code
authored
240 ```ruby
241 class User
242 include Her::Model
243 has_many :comments
d997547 Updated readme for has_one relationship
jfcixmedia authored
244 has_one :role
875f744 Rémi Prévost Update README for belongs_to
authored
245 belongs_to :organization
6878101 Rémi Prévost Update documentation with new API code
authored
246 end
247
248 class Comment
249 include Her::Model
250 end
d997547 Updated readme for has_one relationship
jfcixmedia authored
251
252 class Role
253 include Her::Model
254 end
875f744 Rémi Prévost Update README for belongs_to
authored
255
256 class Organization
257 include Her::Model
258 end
313c487 Rémi Prévost Add better documentation for relationships
authored
259 ```
260
6bd587d Rémi Prévost Improve README, yay!
authored
261 If there’s relationship data in the resource, no extra HTTP request is made when calling the `#comments` method and an array of resources is returned:
6878101 Rémi Prévost Update documentation with new API code
authored
262
313c487 Rémi Prévost Add better documentation for relationships
authored
263 ```ruby
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
264 @user = User.find(1)
265 # {
266 # :data => {
267 # :id => 1,
268 # :name => "George Michael Bluth",
269 # :comments => [
270 # { :id => 1, :text => "Foo" },
271 # { :id => 2, :text => "Bar" }
272 # ],
273 # :role => { :id => 1, :name => "Admin" },
274 # :organization => { :id => 2, :name => "Bluth Company" }
275 # }
276 # }
277 @user.comments
278 # [#<Comment id=1 text="Foo">, #<Comment id=2 text="Bar">]
279 @user.role
280 # #<Role id=1 name="Admin">
281 @user.organization
282 # #<Organization id=2 name="Bluth Company">
313c487 Rémi Prévost Add better documentation for relationships
authored
283 ```
284
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
285 If there’s no relationship data in the resource, Her makes a HTTP request to retrieve the data.
d997547 Updated readme for has_one relationship
jfcixmedia authored
286
287 ```ruby
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
288 @user = User.find(1)
289 # { :data => { :id => 1, :name => "George Michael Bluth", :organization_id => 2 }}
290
291 # has_many relationship:
292 @user.comments
293 # GET /users/1/comments
294 # [#<Comment id=1>, #<Comment id=2>]
295
296 # has_one relationship:
297 @user.role
298 # GET /users/1/role
299 # #<Role id=1>
300
301 # belongs_to relationship:
302 @user.organization
303 # (the organization id comes from :organization_id, by default)
304 # GET /organizations/2
305 # #<Organization id=2>
875f744 Rémi Prévost Update README for belongs_to
authored
306 ```
307
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
308 Subsequent calls to `#comments`, `#role` and `#organization` will not trigger extra HTTP requests and will return the cached objects.
313c487 Rémi Prévost Add better documentation for relationships
authored
309
3bb8232 Rémi Prévost Add documentation for hooks
authored
310 ## Hooks
311
312 You can add *before* and *after* hooks to your models that are triggered on specific actions (`save`, `update`, `create`, `destroy`):
313
314 ```ruby
315 class User
316 include Her::Model
317 before_save :set_internal_id
318
319 def set_internal_id
320 self.internal_id = 42 # Will be passed in the HTTP request
321 end
322 end
ee90237 Rémi Prévost Add example for hooks
authored
323
324 @user = User.create(:fullname => "Tobias Fünke")
325 # POST /users&fullname=Tobias+Fünke&internal_id=42
3bb8232 Rémi Prévost Add documentation for hooks
authored
326 ```
327
6878101 Rémi Prévost Update documentation with new API code
authored
328 ## Custom requests
329
2c0c171 Rémi Prévost Add support for custom_<method> methods
authored
330 You can easily define custom requests for your models using `custom_get`, `custom_post`, etc.
331
332 ```ruby
333 class User
334 include Her::Model
335 custom_get :popular, :unpopular
336 custom_post :from_default
337 end
338
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
339 User.popular
2c0c171 Rémi Prévost Add support for custom_<method> methods
authored
340 # GET /users/popular
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
341 # [#<User id=1>, #<User id=2>]
2c0c171 Rémi Prévost Add support for custom_<method> methods
authored
342
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
343 User.unpopular
2c0c171 Rémi Prévost Add support for custom_<method> methods
authored
344 # GET /users/unpopular
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
345 # [#<User id=3>, #<User id=4>]
2c0c171 Rémi Prévost Add support for custom_<method> methods
authored
346
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
347 User.from_default(:name => "Maeby Fünke")
2c0c171 Rémi Prévost Add support for custom_<method> methods
authored
348 # POST /users/from_default?name=Maeby+Fünke
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
349 # #<User id=5 name="Maeby Fünke">
2c0c171 Rémi Prévost Add support for custom_<method> methods
authored
350 ```
351
352 You can also use `get`, `post`, `put` or `delete` (which maps the returned data to either a collection or a resource).
6878101 Rémi Prévost Update documentation with new API code
authored
353
17d968c Rémi Prévost Improve support for custom methods
authored
354 ```ruby
355 class User
356 include Her::Model
a7ae25f Rémi Prévost Add support for symbols in custom requests
authored
357 end
358
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
359 User.get(:popular)
a7ae25f Rémi Prévost Add support for symbols in custom requests
authored
360 # GET /users/popular
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
361 # [#<User id=1>, #<User id=2>]
37aef13 Rémi Prévost Add support for `get`, `post`, etc. wrapper methods
authored
362
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
363 User.get(:single_best)
37aef13 Rémi Prévost Add support for `get`, `post`, etc. wrapper methods
authored
364 # GET /users/single_best
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
365 # #<User id=1>
a7ae25f Rémi Prévost Add support for symbols in custom requests
authored
366 ```
367
37aef13 Rémi Prévost Add support for `get`, `post`, etc. wrapper methods
authored
368 Also, `get_collection` (which maps the returned data to a collection of resources), `get_resource` (which maps the returned data to a single resource) or `get_raw` (which yields the parsed data return from the HTTP request) can also be used. Other HTTP methods are supported (`post_raw`, `put_resource`, etc.).
a7ae25f Rémi Prévost Add support for symbols in custom requests
authored
369
370 ```ruby
371 class User
372 include Her::Model
17d968c Rémi Prévost Improve support for custom methods
authored
373
374 def self.popular
37aef13 Rémi Prévost Add support for `get`, `post`, etc. wrapper methods
authored
375 get_collection(:popular)
17d968c Rémi Prévost Improve support for custom methods
authored
376 end
6878101 Rémi Prévost Update documentation with new API code
authored
377
17d968c Rémi Prévost Improve support for custom methods
authored
378 def self.total
37aef13 Rémi Prévost Add support for `get`, `post`, etc. wrapper methods
authored
379 get_raw(:stats) do |parsed_data|
17d968c Rémi Prévost Improve support for custom methods
authored
380 parsed_data[:data][:total_users]
381 end
382 end
383 end
384
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
385 User.popular
386 # GET /users/popular
387 # [#<User id=1>, #<User id=2>]
388 User.total
389 # GET /users/stats
390 # => 42
17d968c Rémi Prévost Improve support for custom methods
authored
391 ```
7f7392f Rémi Prévost Improve README and add LICENSE
authored
392
37aef13 Rémi Prévost Add support for `get`, `post`, etc. wrapper methods
authored
393 You can also use full request paths (with strings instead of symbols).
394
395 ```ruby
396 class User
397 include Her::Model
398 end
399
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
400 User.get("/users/popular")
37aef13 Rémi Prévost Add support for `get`, `post`, etc. wrapper methods
authored
401 # GET /users/popular
1bc8ca4 Tyson Tate Readme fixes for readability / clarity.
tysontate authored
402 # [#<User id=1>, #<User id=2>]
37aef13 Rémi Prévost Add support for `get`, `post`, etc. wrapper methods
authored
403 ```
404
fca11ad Rémi Prévost Use internal parameter to build custom paths
authored
405 ## Custom paths
406
407 You can define custom HTTP paths for your models:
408
409 ```ruby
410 class User
411 include Her::Model
412 collection_path "/hello_users/:id"
413 end
414
415 @user = User.find(1)
416 # GET /hello_users/1
417 ```
418
6bd587d Rémi Prévost Improve README, yay!
authored
419 You can also include custom variables in your paths:
fca11ad Rémi Prévost Use internal parameter to build custom paths
authored
420
421 ```ruby
422 class User
423 include Her::Model
6bd587d Rémi Prévost Improve README, yay!
authored
424 collection_path "/organizations/:organization_id/users"
fca11ad Rémi Prévost Use internal parameter to build custom paths
authored
425 end
426
427 @user = User.find(1, :_organization_id => 2)
428 # GET /organizations/2/users/1
429
430 @user = User.all(:_organization_id => 2)
431 # GET /organizations/2/users
6bd587d Rémi Prévost Improve README, yay!
authored
432
433 @user = User.new(:fullname => "Tobias Fünke", :organization_id => 2)
434 @user.save
435 # POST /organizations/2/users
fca11ad Rémi Prévost Use internal parameter to build custom paths
authored
436 ```
437
cdeb59f Rémi Prévost Add Multiple APIs section in README
authored
438 ## Multiple APIs
439
440 It is possible to use different APIs for different models. Instead of calling `Her::API.setup`, you can create instances of `Her::API`:
441
442 ```ruby
443 # config/initializers/her.rb
444 $my_api = Her::API.new
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
445 $my_api.setup :url => "https://my_api.example.com" do |connection|
446 connection.use Faraday::Request::UrlEncoded
447 connection.use Her::Middleware::DefaultParseJSON
448 connection.use Faraday::Adapter::NetHttp
53744d4 Rémi Prévost Do not set any default middleware
authored
449 end
cdeb59f Rémi Prévost Add Multiple APIs section in README
authored
450
451 $other_api = Her::API.new
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
452 $other_api.setup :url => "https://other_api.example.com" do |connection|
453 connection.use Faraday::Request::UrlEncoded
454 connection.use Her::Middleware::DefaultParseJSON
455 connection.use Faraday::Adapter::NetHttp
53744d4 Rémi Prévost Do not set any default middleware
authored
456 end
cdeb59f Rémi Prévost Add Multiple APIs section in README
authored
457 ```
458
459 You can then define which API a model will use:
460
461 ```ruby
462 class User
463 include Her::Model
464 uses_api $my_api
465 end
466
467 class Category
468 include Her::Model
469 uses_api $other_api
470 end
471
472 User.all
473 # GET https://my_api.example.com/users
474
475 Category.all
476 # GET https://other_api.example.com/categories
477 ```
478
3805014 Rémi Prévost Add SSL section
authored
479 ## SSL
480
481 When initializing `Her::API`, you can pass any parameter supported by `Faraday.new`. So [to use HTTPS](https://github.com/technoweenie/faraday/wiki/Setting-up-SSL-certificates), you can use Faraday’s `:ssl` option.
482
483 ```ruby
484 ssl_options = { :ca_path => "/usr/lib/ssl/certs" }
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
485 Her::API.setup :url => "https://api.example.com", :ssl => ssl_options do |connection|
486 connection.use Faraday::Request::UrlEncoded
487 connection.use Her::Middleware::DefaultParseJSON
488 connection.use Faraday::Adapter::NetHttp
3805014 Rémi Prévost Add SSL section
authored
489 end
490 ```
491
c4108fa Rémi Prévost Add README section for testing models
authored
492 ## Testing
493
494 Using Faraday stubbing feature, it’s very easy to write tests for our models. For example, using [RSpec](https://github.com/rspec/rspec-core):
495
496 ```ruby
497 # app/models/post.rb
498 class Post
499 include Her::Model
500 custom_get :popular
501 end
502
503 # spec/models/post.rb
504 describe Post do
505 before do
1afdd82 Rémi Prévost Replace “builder” with “connection” in docs and code
authored
506 Her::API.setup :url => "http://api.example.com" do |connection|
507 connection.use Her::Middleware::FirstLevelParseJSON
508 connection.use Faraday::Request::UrlEncoded
509 connection.adapter :test do |stub|
c4108fa Rémi Prévost Add README section for testing models
authored
510 stub.get("/users/popular") { |env| [200, {}, [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }].to_json] }
511 end
512 end
513 end
514
515 describe ".popular" do
516 it "should fetch all popular posts" do
517 @posts = Post.popular
518 @posts.length.should == 2
519 end
520 end
521 end
522 ```
523
7f7392f Rémi Prévost Improve README and add LICENSE
authored
524 ## Things to be done
525
a6e9967 Rémi Prévost Update README with more examples
authored
526 * Better error handling
6bd587d Rémi Prévost Improve README, yay!
authored
527 * Better API documentation (using YARD)
7f7392f Rémi Prévost Improve README and add LICENSE
authored
528
676a56f Rémi Prévost Improve Contribute section in README
authored
529 ## Contribute
7f7392f Rémi Prévost Improve README and add LICENSE
authored
530
676a56f Rémi Prévost Improve Contribute section in README
authored
531 Yes please! Feel free to contribute and submit issues/pull requests [on GitHub](https://github.com/remiprev/her/issues).
532
533 ### How to contribute
534
535 * Fork the repository
536 * Implement your feature or fix
537 * Add examples that describe it (in the `spec` directory)
538 * Make sure `bundle exec rake spec` passes after your modifications
539 * Commit (bonus points for doing it in a `feature-*` branch)
540 * Send a pull request!
541
542 ### Contributors
543
544 These fine folks helped with Her:
7f9f399 Rémi Prévost Add contributors, woohoo!
authored
545
546 * [@jfcixmedia](https://github.com/jfcixmedia)
547 * [@EtienneLem](https://github.com/EtienneLem)
a366819 Rémi Prévost Add @rafaelss to contributors
authored
548 * [@rafaelss](https://github.com/rafaelss)
855b897 Rémi Prévost Update contributors with @tysontate
authored
549 * [@tysontate](https://github.com/tysontate)
2163cf5 Rémi Prévost Add Nicolas Fouché to contributors list
authored
550 * [@nfo](https://github.com/nfo)
f18374a Rémi Prévost Add @simonprevost to contributors
authored
551 * [@simonprevost](https://github.com/simonprevost)
7f7392f Rémi Prévost Improve README and add LICENSE
authored
552
553 ## License
554
fd5bb21 François Bernier Show the correct license name in README
fbernier authored
555 Her is © 2012 [Rémi Prévost](http://exomel.com) and may be freely distributed under the [MIT license](https://github.com/remiprev/her/blob/master/LICENSE). See the `LICENSE` file.
Something went wrong with that request. Please try again.