flexirest 1.6.5 → 1.6.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +92 -1243
  4. data/docs/associations.md +181 -0
  5. data/docs/authentication.md +76 -0
  6. data/docs/automatic-conversion-of-fields-to-datedatetime.md +34 -0
  7. data/docs/basic-usage.md +103 -0
  8. data/docs/body-types.md +33 -0
  9. data/docs/caching.md +26 -0
  10. data/docs/combined-example.md +72 -0
  11. data/docs/debugging.md +32 -0
  12. data/docs/default-parameters.md +37 -0
  13. data/docs/faking-calls.md +22 -0
  14. data/docs/faraday-configuration.md +28 -0
  15. data/docs/filtering-result-lists.md +16 -0
  16. data/docs/httpparse-error-handling.md +17 -0
  17. data/{CONTRIBUTING.md → docs/internals.md} +4 -6
  18. data/docs/json-api.md +42 -0
  19. data/docs/lazy-loading.md +31 -0
  20. data/{Migrating-from-ActiveRestClient.md → docs/migrating-from-activerestclient.md} +2 -2
  21. data/docs/parallel-requests.md +28 -0
  22. data/docs/per-request-parameter-encoding.md +32 -0
  23. data/docs/per-request-timeouts.md +13 -0
  24. data/docs/plain-requests.md +30 -0
  25. data/docs/proxying-apis.md +86 -0
  26. data/docs/raw-requests.md +38 -0
  27. data/docs/required-parameters.md +17 -0
  28. data/docs/root-elements.md +34 -0
  29. data/{Ruby-on-Rails-Integration.md → docs/ruby-on-rails-integration.md} +16 -12
  30. data/docs/{Flexirest Internals.graffle → source/Flexirest Internals.graffle} +0 -0
  31. data/docs/{Flexirest Logo.sketch → source/Flexirest Logo.sketch} +0 -0
  32. data/docs/translating-apis.md +31 -0
  33. data/docs/updating-only-changed-dirty-attributes.md +37 -0
  34. data/docs/using-callbacks.md +114 -0
  35. data/docs/validation.md +89 -0
  36. data/docs/xml-responses.md +58 -0
  37. data/lib/flexirest/configuration.rb +36 -20
  38. data/lib/flexirest/request.rb +12 -4
  39. data/lib/flexirest/version.rb +1 -1
  40. data/spec/lib/request_spec.rb +28 -0
  41. metadata +35 -7
@@ -0,0 +1,181 @@
1
+ # *Flexirest:* Associations
2
+
3
+ There are two types of association. One assumes when you call a method you actually want it to call the method on a separate class (as that class has other methods that are useful). The other is lazy loading related classes from a separate URL.
4
+
5
+ ## Type 1 - Loading Other Classes
6
+
7
+ If the call would return a single instance or a list of instances that should be considered another object, you can also specify this when mapping the method using the `:has_one` or `:has_many` options respectively. It doesn't call anything on that object except for instantiate it, but it does let you have objects of a different class to the one you initially called.
8
+
9
+ ```ruby
10
+ class Expense < Flexirest::Base
11
+ def inc_vat
12
+ ex_vat * 1.20
13
+ end
14
+ end
15
+
16
+ class Address < Flexirest::Base
17
+ def full_string
18
+ "#{self.street}, #{self.city}, #{self.region}, #{self.country}"
19
+ end
20
+ end
21
+
22
+ class Person < Flexirest::Base
23
+ get :find, "/people/:id", :has_many => {:expenses => Expense},
24
+ :has_one => {:address => Address}
25
+ end
26
+
27
+ @person = Person.find(1)
28
+ puts @person.expenses.reduce {|e| e.inc_vat}
29
+ puts @person.address.full_string
30
+ ```
31
+
32
+ You can also use `has_one`/`has_many` on the class level to allow chaining of classes. You can specify the class name or allow the system to automatically convert it to the singular class. For example:
33
+
34
+ ```ruby
35
+ class Expense < Flexirest::Base
36
+ def inc_vat
37
+ ex_vat * 1.20
38
+ end
39
+ end
40
+
41
+ class Address < Flexirest::Base
42
+ def full_string
43
+ "#{self.street}, #{self.city}, #{self.region}, #{self.country}"
44
+ end
45
+ end
46
+
47
+ class Person < Flexirest::Base
48
+ has_one :addresses
49
+ has_many :expenses, Expense
50
+ get :find, "/people/:id"
51
+ end
52
+
53
+ class Company < Flexirest::Base
54
+ has_many :people
55
+ get :find, "/companies/:id"
56
+ end
57
+ ```
58
+
59
+ Sometimes we want attributes to just return a simple Ruby Array. To achieve this we can add an `:array` option to the method. This is especially useful when the attribute contains an array of scalar values. If you don't specify the `:array` option Flexirest will return a `Flexirest::ResultIterator`. To illustrate the difference consider the following example:
60
+
61
+ ```ruby
62
+ class Book < Flexirest::Base
63
+ # :authors attribute ["Robert T. Kiyosaki", "Sharon L. Lechter C.P.A"]
64
+ # :genres attribute ["self-help", "finance", "education"]
65
+ get :find, "/books/:name", array: [:authors]
66
+ end
67
+ ```
68
+
69
+ In the example above, the following results can be observed:
70
+
71
+ ```ruby
72
+ @book = Book.find("rich-dad-poor-dad")
73
+ puts @book.authors
74
+ #=> ["Robert T. Kiyosaki", "Sharon L. Lechter C.P.A"]
75
+ puts @book.authors.class
76
+ #=> Array
77
+ puts @book.genres
78
+ #=> #<Flexirest::ResultIterator:0x007ff420fe7a88 @_status=nil, @_headers=nil, @items=["self-help", "finance", "education"]>
79
+ puts @books.genres.class
80
+ #=> Flexirest::ResultIterator
81
+ puts @books.genres.items
82
+ #=> ["self-help", "finance", "education"]
83
+ ```
84
+
85
+ When the `:array` option includes an attribute, it is assumed the values were returned with the request, and they will not be lazily loaded. It is also assumed the attribute values do not map to a Flexirest resource.
86
+
87
+ ## Type 2 - Lazy Loading From Other URLs
88
+
89
+ When mapping the method, passing a list of attributes will cause any requests for those attributes to mapped to the URLs given in their responses. The response for the attribute may be one of the following:
90
+
91
+ ```ruby
92
+ "attribute" : "URL"
93
+ "attribute" : ["URL", "URL"]
94
+ "attribute" : { "url" : "URL"}
95
+ "attribute" : { "href" : "URL"}
96
+ "attribute" : { "something" : "URL"}
97
+ ```
98
+
99
+ The difference between the last 3 examples is that a key of `url` or `href` signifies it's a single object that is lazy loaded from the value specified. Any other keys assume that it's a nested set of URLs (like in the array situation, but accessible via the keys - e.g. object.attribute.something in the above example).
100
+
101
+ It is required that the URL is a complete URL including a protocol starting with "http". To configure this use code like:
102
+
103
+ ```ruby
104
+ class Person < Flexirest::Base
105
+ get :find, "/people/:id", :lazy => [:orders, :refunds]
106
+ end
107
+ ```
108
+
109
+ And use it like this:
110
+
111
+ ```ruby
112
+ # Makes a call to /people/1
113
+ @person = Person.find(1)
114
+
115
+ # Makes a call to the first URL found in the "books":[...] array in the article response
116
+ # only makes the HTTP request when first used though
117
+ @person.books.first.name
118
+ ```
119
+
120
+ ## Type 3 - HAL Auto-loaded Resources
121
+
122
+ You don't need to define lazy attributes if they are defined using [HAL](http://stateless.co/hal_specification.html) (with an optional embedded representation). If your resource has an `_links` item (and optionally an `_embedded` item) then it will automatically treat the linked resources (with the `_embedded` cache) as if they were defined using `:lazy` as per type 2 above.
123
+
124
+ If you need to, you can access properties of the HAL association. By default just using the HAL association gets the embedded resource (or requests the remote resource if not available in the `_embedded` list).
125
+
126
+ ```ruby
127
+ @person = Person.find(1)
128
+ @person.students[0]._hal_attributes("title")
129
+ ```
130
+
131
+ ## Type 4 - Nested Resources
132
+
133
+ It's common to have resources that are logically children of other resources. For example, suppose that your API includes these endpoints:
134
+
135
+ | HTTP Verb | Path | |
136
+ |-----------|-----------------------------|------------------------------------------|
137
+ | POST | /magazines/:magazine_id/ads | create a new ad belonging to a magazine |
138
+ | GET | /magazines/:magazine_id/ads | display a list of all ads for a magazine |
139
+
140
+ In these cases, your child class will contain the following:
141
+
142
+ ```ruby
143
+ class Ad < Flexirest::Base
144
+ post :create, "/magazines/:magazine_id/ads"
145
+ get :all, "/magazines/:magazine_id/ads"
146
+ end
147
+ ```
148
+
149
+ You can then access Ads by specifying their magazine IDs:
150
+
151
+ ```ruby
152
+ Ad.all(magazine_id: 1)
153
+ Ad.create(magazine_id: 1, title: "My Add Title")
154
+ ```
155
+
156
+ ## Type 5 - JSON API Auto-loaded Resources
157
+
158
+ If attributes are defined using [JSON API](http://jsonapi.org), you don't need to define lazy attributes. If your resource has a `links` object with a `related` item, it will automatically treat the linked resources as if they were defined using `:lazy`.
159
+
160
+ You need to activate JSON API by specifying the `json_api` proxy:
161
+
162
+ ```ruby
163
+ class Article < Flexirest::Base
164
+ proxy :json_api
165
+ end
166
+ ```
167
+
168
+ If you want to embed linked resources directly in the response (i.e. request a JSON API compound document), use the `includes` class method. The linked resource is accessed in the same was as if it was lazily loaded, but without the extra request:
169
+
170
+ ```ruby
171
+ # Makes a call to /articles with parameters: include=images
172
+ Article.includes(:images).all
173
+
174
+ # For nested resources, the include parameter becomes: include=images.tags,images.photographer
175
+ Article.includes(:images => [:tags, :photographer]).all
176
+ ```
177
+
178
+
179
+ -----
180
+
181
+ [< Faraday configuration](faraday-configuration.md) | [Combined example >](combined-example.md)
@@ -0,0 +1,76 @@
1
+ # *Flexirest:* Authentication
2
+
3
+ ## Basic authentication
4
+
5
+ You can authenticate with Basic authentication by putting the username and password in to the `base_url` or by setting them within the specific model:
6
+
7
+ ```ruby
8
+ class Person < Flexirest::Base
9
+ username 'api'
10
+ password 'eb693ec-8252c-d6301-02fd0-d0fb7-c3485'
11
+
12
+ # ...
13
+ end
14
+ ```
15
+
16
+ You can also pass in a Proc or a block to `username` and `password` if you want to dynamically pull it from somewhere, e.g. a [Current class descending from ActiveSupport::CurrentAttributes](http://edgeapi.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html).
17
+
18
+ ```ruby
19
+ class Person < Flexirest::Base
20
+ username -> (obj) { obj ? Account.find(obj.id).username : Current.username }
21
+ password do
22
+ Rails.configuration.x.default_password
23
+ end
24
+
25
+ get :all, "/people"
26
+ get :find, "/people/:id"
27
+ end
28
+ ```
29
+
30
+ In the above example, the `username` call handles things differently if it's called from an object context:
31
+
32
+ ```ruby
33
+ person = Person.new(id: 1234)
34
+ person.find
35
+ ```
36
+
37
+ Or if it's called from a class context:
38
+
39
+ ```ruby
40
+ Person.find(id: 1234)
41
+ ```
42
+
43
+ ## Api-Auth
44
+
45
+ Using the [Api-Auth](https://github.com/mgomes/api_auth) integration it is very easy to sign requests. Include the Api-Auth gem in your `Gemfile` and then add it to your application. Then simply configure Api-Auth one time in your app and all requests will be signed from then on.
46
+
47
+ ```ruby
48
+ require 'api-auth'
49
+
50
+ @access_id = '123456'
51
+ @secret_key = 'abcdef'
52
+ Flexirest::Base.api_auth_credentials(@access_id, @secret_key)
53
+ ```
54
+
55
+ You can also specify different credentials for different models just like configuring `base_url`:
56
+
57
+ ```ruby
58
+ class Person < Flexirest::Base
59
+ api_auth_credentials '123456', 'abcdef'
60
+ end
61
+ ```
62
+
63
+ For more information on how to generate an access id and secret key please read the [Api-Auth](https://github.com/mgomes/api_auth) documentation.
64
+
65
+ If you want to specify either the `:digest` or `:override_http_method` to ApiAuth, you can pass these in as options after the access ID and secret key, for example:
66
+
67
+ ```ruby
68
+ class Person < Flexirest::Base
69
+ api_auth_credentials '123456', 'abcdef', digest: "sha256"
70
+ end
71
+ ```
72
+
73
+
74
+ -----
75
+
76
+ [< Lazy loading](lazy-loading.md) | [Body types >](body-types.md)
@@ -0,0 +1,34 @@
1
+ # *Flexirest:* Automatic conversion of fields to Date/DateTime
2
+
3
+ By default Flexirest will attempt to convert all fields to a `Date` or `DateTime` object if it's a string and the value matches certain regular expressions. However, on large responses this can be computationally expensive. You can disable this automatic conversion completely with:
4
+
5
+ ```ruby
6
+ Flexirest::Base.disable_automatic_date_parsing = true
7
+ ```
8
+
9
+ Additionally, you can specify when mapping the methods which fields should be parsed (so you can disable it in general, then apply it to particular known fields):
10
+
11
+ ```ruby
12
+ class Person < Flexirest::Base
13
+ get :all, '/people', parse_fields: [:created_at, :updated_at]
14
+ end
15
+ ```
16
+
17
+ It is also possible to whitelist fields that should be parsed in your models, which is useful if you are instantiating these objects directly. The specified fields also apply automatically to request mapping.
18
+
19
+ ```ruby
20
+ class Person < Flexirest::Base
21
+ parse_date :updated_at, :created_at
22
+ end
23
+
24
+ # to disable all mapping
25
+ class Disabled < Flexirest::Base
26
+ parse_date :none
27
+ end
28
+ ```
29
+
30
+ This system respects `disable_automatic_date_parsing`, and will default to mapping everything - unless a `parse_date` whitelist is specified, or automatic parsing is globally disabled.
31
+
32
+ -----
33
+
34
+ [< Per-request parameter encoding](per-request-parameter-encoding.md) | [Raw requests >](raw-requests.md)
@@ -0,0 +1,103 @@
1
+ # *Flexirest:* Basic usage
2
+
3
+ First you need to create your new model class `app/models/person.rb`:
4
+
5
+ ```ruby
6
+ class Person < Flexirest::Base
7
+ base_url "https://www.example.com/api/v1"
8
+
9
+ get :all, "/people"
10
+ get :find, "/people/:id"
11
+ put :save, "/people/:id"
12
+ post :create, "/people"
13
+ delete :remove, "/people/:id"
14
+ end
15
+ ```
16
+
17
+ Note I've specified the `base_url` in the class above. This is useful where you want to be explicit or use different APIs for some classes and be explicit. If you have one server that's generally used, you can set it once with a simple line in a `config/initializer/{something}.rb` file:
18
+
19
+ ```ruby
20
+ Flexirest::Base.base_url = "https://www.example.com/api/v1"
21
+ ```
22
+
23
+ Any `base_url` settings in specific classes override this declared default. You can also assign an array of URLs to `base_url` and Flexirest will randomly pull one of the URLs for each request, giving you a very simplistic load balancing (it doesn't know about the health or load levels of the backends).
24
+
25
+ You can then use your new class like this:
26
+
27
+ ```ruby
28
+ # Create a new person
29
+ @person = Person.create(
30
+ first_name:"John"
31
+ last_name:"Smith"
32
+ )
33
+
34
+ # Find a person (not needed after creating)
35
+ id = @person.id
36
+ @person = Person.find(id)
37
+
38
+ # Update a person
39
+ @person.last_name = "Jones"
40
+ @person.save
41
+
42
+ # Get all people
43
+ @people = Person.all
44
+ @people.each do |person|
45
+ puts "Hi " + person.first_name
46
+ end
47
+ ```
48
+
49
+ For `delete` requests whether an API can handle a body or not is undefined. The default is to ignore any parameters not sent in the URL named parameters, but you can optionally specify `send_delete_body` and it will encode them in your chosen way into the body.
50
+
51
+ ```
52
+ delete :remove, "/people/:id", send_delete_body: true
53
+ ```
54
+
55
+ If an API returns an array of results and you have [will_paginate](https://rubygems.org/gems/will_paginate) installed then you can call the paginate method to return a particular page of the results (note: this doesn't reduce the load on the server, but it can help with pagination if you have a cached response).
56
+
57
+ ```ruby
58
+ @people = Person.all
59
+ @people.paginate(page: 1, per_page: 10).each do |person|
60
+ puts "You made the first page: " + person.first_name
61
+ end
62
+ ```
63
+
64
+ Note, you can assign to any attribute, whether it exists or not before and read from any attribute (which will return nil if not found). If you pass a string or a number to a method it will assume that it's for the "id" field. Any other field values must be passed as a hash and you can't mix passing a string/number and a hash.
65
+
66
+ ```ruby
67
+ @person = Person.find(1234) # valid
68
+ @person = Person.find("1234") # valid
69
+ @person = Person.find(:id => 1234) # valid
70
+ @person = Person.find(:id => 1234, :name => "Billy") # valid
71
+ @person = Person.find(1234, :name => "Billy") # invalid
72
+ ```
73
+
74
+ You can also call any mapped method as an instance variable which will pass the current attribute set in as parameters (either GET or POST depending on the mapped method type). If the method returns a single instance it will assign the attributes of the calling object and return itself. If the method returns a list of instances, it will only return the list. So, we could rewrite the create call above as:
75
+
76
+ ```ruby
77
+ @person = Person.new
78
+ @person.first_name = "John"
79
+ @person.last_name = "Smith"
80
+ @person.create
81
+ puts @person.id
82
+ ```
83
+
84
+ The response of the #create call set the attributes at that point (any manually set attributes before that point are removed).
85
+
86
+ If you have attributes beginning with a number, Ruby doesn't like this. So, you can use hash style notation to read/write the attributes:
87
+
88
+ ```ruby
89
+ @tv = Tv.find(model:"UE55U8000") # { "properties" : {"3d" : false} }
90
+ puts @tv.properties["3d"]
91
+ @tv.properties["3d"] = true
92
+ ```
93
+
94
+ If you want to debug the response, using inspect on the response object may well be useful. However, if you want a simpler output, then you can call `#to_json` on the response object:
95
+
96
+ ```ruby
97
+ @person = Person.find(email:"something@example.com")
98
+ puts @person.to_json
99
+ ```
100
+
101
+ -----
102
+
103
+ [< Introduction](../README.md) | [Ruby on Rails integration >](ruby-on-rails-integration.md)
@@ -0,0 +1,33 @@
1
+ # *Flexirest:* Body types
2
+
3
+ By default Flexirest formats the request bodies as normal CGI parameters in `K=V&K2=V2` format. However, if you want to use JSON for your PUT/POST requests, you can use choose to configure Flexirest to do so (the other option, the default, is `:form_encoded`):
4
+
5
+ ```ruby
6
+ class Person < Flexirest::Base
7
+ request_body_type :json
8
+ # ...
9
+ end
10
+ ```
11
+
12
+ or
13
+
14
+ ```ruby
15
+ Flexirest::Base.request_body_type = :json
16
+ ```
17
+
18
+ This will also set the header `Content-Type` to `application/x-www-form-urlencoded` by default or `application/json; charset=utf-8` when `:json`. You can override this using the callback `before_request`.
19
+
20
+ If you have an API that is inconsistent in its body type requirements, you can also specify it on the individual method mapping:
21
+
22
+ ```ruby
23
+ class Person < Flexirest::Base
24
+ request_body_type :form_encoded # This is the default, but just for demo purposes
25
+
26
+ get :all, '/people', request_body_type: :json
27
+ end
28
+ ```
29
+
30
+
31
+ -----
32
+
33
+ [< Authentication](authentication.md) | [Parallel requests >](parallel-requests.md)
data/docs/caching.md ADDED
@@ -0,0 +1,26 @@
1
+ # *Flexirest:* Caching
2
+
3
+ Expires and ETag based caching is enabled by default, but with a simple line in the application.rb/production.rb you can disable it:
4
+
5
+ ```ruby
6
+ Flexirest::Base.perform_caching = false
7
+ ```
8
+
9
+ or you can disable it per classes with:
10
+
11
+ ```ruby
12
+ class Person < Flexirest::Base
13
+ perform_caching false
14
+ end
15
+ ```
16
+
17
+ If Rails is defined, it will default to using Rails.cache as the cache store, if not, you'll need to configure one with a `ActiveSupport::Cache::Store` compatible object using:
18
+
19
+ ```ruby
20
+ Flexirest::Base.cache_store = Redis::Store.new("redis://localhost:6379/0/cache")
21
+ ```
22
+
23
+
24
+ -----
25
+
26
+ [< Combined example](combined-example.md) | [Using callbacks >](using-callbacks.md)
@@ -0,0 +1,72 @@
1
+ # *Flexirest:* Combined example
2
+
3
+ OK, so let's say you have an API for getting articles. Each article has a property called `title` (which is a string) and a property `images` which includes a list of URIs. Following this URI would take you to a image API that returns the image's `filename` and `filesize`. We'll also assume this is a HAL compliant API. We would declare our two models (one for articles and one for images) like the following:
4
+
5
+ ```ruby
6
+ class Article < Flexirest::Base
7
+ get :find, '/articles/:id', has_many:{:images => Image} # ,lazy:[:images] isn't needed as we're using HAL
8
+ end
9
+
10
+ class Image < Flexirest::Base
11
+ # You may have mappings here
12
+
13
+ def nice_size
14
+ "#{size/1024}KB"
15
+ end
16
+ end
17
+ ```
18
+
19
+ We assume the /articles/:id call returns something like the following:
20
+
21
+ ```json
22
+ {
23
+ "title": "Fly Fishing",
24
+ "author": "J R Hartley",
25
+ "images": [
26
+ "http://api.example.com/images/1",
27
+ "http://api.example.com/images/2"
28
+ ]
29
+ }
30
+ ```
31
+
32
+ We said above that the /images/:id call would return something like:
33
+
34
+ ```json
35
+ {
36
+ "filename": "http://cdn.example.com/images/foo.jpg",
37
+ "filesize": 123456
38
+ }
39
+ ```
40
+
41
+ When it comes time to use it, you would do something like this:
42
+
43
+ ```ruby
44
+ @article = Article.find(1)
45
+ @article.images.is_a?(Flexirest::LazyAssociationLoader)
46
+ @article.images.size == 2
47
+ @article.images.each do |image|
48
+ puts image.inspect
49
+ end
50
+ ```
51
+
52
+ At this point, only the HTTP call to '/articles/1' has been made. When you actually start using properties of the images list/image object then it makes a call to the URL given in the images list and you can use the properties as if it was a nested JSON object in the original response instead of just a URL:
53
+
54
+ ```ruby
55
+ @image = @article.images.first
56
+ puts @image.filename
57
+ # => http://cdn.example.com/images/foo.jpg
58
+ puts @image.filesize
59
+ # => 123456
60
+ ```
61
+
62
+ You can also treat `@image` looks like an Image class (and you should 100% treat it as one) it's technically a lazy loading proxy. So, if you cache the views for your application should only make HTTP API requests when actually necessary.
63
+
64
+ ```ruby
65
+ puts @image.nice_size
66
+ # => 121KB
67
+ ```
68
+
69
+
70
+ -----
71
+
72
+ [< Associations](associations.md) | [Caching >](caching.md)
data/docs/debugging.md ADDED
@@ -0,0 +1,32 @@
1
+ # *Flexirest:* Debugging
2
+
3
+ You can turn on verbose debugging to see what is sent to the API server and what is returned in one of these two ways:
4
+
5
+ ```ruby
6
+ class Article < Flexirest::Base
7
+ verbose true
8
+ end
9
+
10
+ class Person < Flexirest::Base
11
+ verbose!
12
+ end
13
+ ```
14
+
15
+ By default verbose logging isn't enabled, so it's up to the developer to enable it (and remember to disable it afterwards). It does use debug level logging, so it shouldn't fill up a correctly configured production server anyway.
16
+
17
+ If you prefer to record the output of an API call in a more automated fashion you can use a callback called `record_response` like this:
18
+
19
+ ```ruby
20
+ class Article < Flexirest::Base
21
+ record_response do |url, response|
22
+ File.open(url.parameterize, "w") do |f|
23
+ f << response.body
24
+ end
25
+ end
26
+ end
27
+ ```
28
+
29
+
30
+ -----
31
+
32
+ [< Filtering result lists](filtering-result-lists.md) | [XML responses >](xml-responses.md)
@@ -0,0 +1,37 @@
1
+ # *Flexirest:* Default parameters
2
+
3
+ If you want to specify default parameters you shouldn't use a path like:
4
+
5
+ ```ruby
6
+ class Person < Flexirest::Base
7
+ get :all, '/people?all=true' # THIS IS WRONG!!!
8
+ end
9
+ ```
10
+
11
+ You should use a defaults option to specify the defaults, then they will be correctly overwritten when making the request
12
+
13
+ ```ruby
14
+ class Person < Flexirest::Base
15
+ get :all, '/people', :defaults => {:active => true}
16
+ end
17
+
18
+ @people = Person.all(active:false)
19
+ ```
20
+
21
+ If you specify `defaults` as a `Proc` this will be executed with the set parameters (which you can change). For example to allow you to specify a reference (but the API wants it formated as "id-reference") you could use:
22
+
23
+ ```ruby
24
+ class Person < Flexirest::Base
25
+ get :all, "/", defaults: (Proc.new do |params|
26
+ reference = params.delete(:reference) # Delete the old parameter
27
+ {
28
+ id: "id-#{reference}"
29
+ } # The last thing is the hash of defaults
30
+ end)
31
+ end
32
+ ```
33
+
34
+
35
+ -----
36
+
37
+ [< Translating APIs](translating-apis.md) | [Root elements >](root-elements.md)
@@ -0,0 +1,22 @@
1
+ # *Flexirest:* Faking calls
2
+
3
+ There are times when an API hasn't been developed yet, so you want to fake the API call response. To do this, you can simply pass a `:fake` option when mapping the call containing the response.
4
+
5
+ ```ruby
6
+ class Person < Flexirest::Base
7
+ get :all, '/people', fake: [{first_name:"Johnny"}, {first_name:"Bob"}]
8
+ end
9
+ ```
10
+
11
+ You may want to run a proc when faking data (to put information from the parameters in to the response or return different responses depending on the parameters). To do this just pass a proc to `:fake`:
12
+
13
+ ```ruby
14
+ class Person < Flexirest::Base
15
+ get :all, '/people', fake: ->(request) { {result: request.get_params[:id]} }
16
+ end
17
+ ```
18
+
19
+
20
+ -----
21
+
22
+ [< Parallel requests](parallel-requests.md) | [Per-request timeouts >](per-request-timeouts.md)
@@ -0,0 +1,28 @@
1
+ # *Flexirest:* Faraday configuration
2
+
3
+ Flexirest uses Faraday to allow switching HTTP backends, the default is to just use Faraday's default. To change the used backend just set it in the class by setting `adapter` to a Faraday supported adapter symbol.
4
+
5
+ ```ruby
6
+ Flexirest::Base.adapter = :net_http
7
+ # or ...
8
+ Flexirest::Base.adapter = :patron
9
+ ```
10
+
11
+ In versions before 1.2.0 the adapter was hardcoded to `:patron`, so if you want to ensure it still uses Patron, you should set this setting.
12
+
13
+ If you want more control you can pass a **complete** configuration block ("complete" means that the block does not _override_ [the default configuration](https://github.com/flexirest/flexirest/blob/5b1953d89e26c02ca74f74464ccb7cd4c9439dcc/lib/flexirest/configuration.rb#L184-L201), but rather _replaces_ it).
14
+
15
+ For available configuration variables look into the [Faraday documentation](https://github.com/lostisland/faraday).
16
+
17
+ ```ruby
18
+ Flexirest::Base.faraday_config do |faraday|
19
+ faraday.adapter(:net_http)
20
+ faraday.options.timeout = 10
21
+ faraday.headers['User-Agent'] = "Flexirest/#{Flexirest::VERSION}"
22
+ end
23
+ ```
24
+
25
+
26
+ -----
27
+
28
+ [< Ruby on Rails integration](ruby-on-rails-integration.md) | [Associations >](associations.md)
@@ -0,0 +1,16 @@
1
+ # *Flexirest:* Filtering result lists
2
+
3
+ If the API returns a JSON list of items, this is retured to you as a `Flexirest::ResultIterator` object. A `ResultIterator` sorts simple filtering of the list using a `where` method based on values matching a specified criteria (or matching using regular expressions):
4
+
5
+ ```ruby
6
+ class Article < Flexirest::Base
7
+ get :all, "/articles"
8
+ end
9
+
10
+ Article.all.where(published: true, department: /technical\-/)
11
+ ```
12
+
13
+
14
+ -----
15
+
16
+ [< Validation](validation.md) | [Debugging >](debugging.md)