reynard 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +112 -11
- data/lib/reynard/model.rb +5 -1
- data/lib/reynard/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2942c304a1a9caaae88253e2bce40188b79bb8a5d25ccd93c8e9a04f7730e386
|
4
|
+
data.tar.gz: 12948419634f2926ae083ae364bd35f48a6b79b8f6308df95b80baafe061dce6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bcf669808d10dfff594861274b301ff77c99038ddea5e121b0ccd61336beb7089e6c20f4e566c9a29e5b813194f5b79d07c7c067c720b6b303de8c07e862944
|
7
|
+
data.tar.gz: 64f7877a9a9e44c77cb357ff36d2ecac691cfce668dc2ba2197f0b68a284e0127fab96c099ca3cb99c0390658466a4fcda3569a2e2479e643d73f95d06cf2a16
|
data/README.md
CHANGED
@@ -48,7 +48,7 @@ reynard.base_url(base_url)
|
|
48
48
|
|
49
49
|
## Calling endpoints
|
50
50
|
|
51
|
-
Assuming there is an operation
|
51
|
+
Assuming there is an operation with the `operationId` set to `employeeByUuid` you can perform a request as shown below. Note that `operationId` is a required property in the specs.
|
52
52
|
|
53
53
|
```ruby
|
54
54
|
response = reynard.
|
@@ -57,7 +57,7 @@ response = reynard.
|
|
57
57
|
execute
|
58
58
|
```
|
59
59
|
|
60
|
-
When an operation requires a body, you can add it as structured data.
|
60
|
+
When an operation requires a body, you can add it as structured data. It will be converted to JSON automatically.
|
61
61
|
|
62
62
|
```ruby
|
63
63
|
response = reynard.
|
@@ -66,13 +66,7 @@ response = reynard.
|
|
66
66
|
execute
|
67
67
|
```
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
```ruby
|
72
|
-
response.object.name #=> 'Sam Seven'
|
73
|
-
```
|
74
|
-
|
75
|
-
The response object shared much of its interface with `Net::HTTP::Response`.
|
69
|
+
The response object shares much of its interface with `Net::HTTP::Response`.
|
76
70
|
|
77
71
|
```ruby
|
78
72
|
response.code #=> '200'
|
@@ -82,6 +76,24 @@ response.body #=> '{"name":"Sam Seven"}'
|
|
82
76
|
response.parsed_body #=> { "name" => "Sam Seven" }
|
83
77
|
```
|
84
78
|
|
79
|
+
You can test for groups of response codes, basically matching `1xx` through `5xx`.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
response.informational?
|
83
|
+
response.success?
|
84
|
+
response.redirection?
|
85
|
+
response.client_error?
|
86
|
+
response.server_error?
|
87
|
+
```
|
88
|
+
|
89
|
+
In case the response status and content-type matches a response in the specification it will attempt to build an object using the specified schema.
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
response.object.name #=> 'Sam Seven'
|
93
|
+
```
|
94
|
+
|
95
|
+
See below for more details about the object builder.
|
96
|
+
|
85
97
|
## Schema and models
|
86
98
|
|
87
99
|
Reynard has an object builder that allows you to get a value object backed by model classes based on the resource schema.
|
@@ -189,7 +201,7 @@ There are two alternatives for accessing this property:
|
|
189
201
|
# parsed JSON on the response object.
|
190
202
|
response.parsed_body["1st-class"]
|
191
203
|
# When you are processing nested models and you don't have access to the
|
192
|
-
# response object, you can
|
204
|
+
# response object, you can choose to use the `[]` method.
|
193
205
|
response.object["1st-class"]
|
194
206
|
# Don't use `send` to access the property, this may not work in future
|
195
207
|
# versions.
|
@@ -198,7 +210,7 @@ response.object.send("1st-class")
|
|
198
210
|
|
199
211
|
#### Mapping properties
|
200
212
|
|
201
|
-
In case you are forced to access a property through a method, you could
|
213
|
+
In case you are forced to access a property through a method, you could choose to map irregular property names to method names globally for all models:
|
202
214
|
|
203
215
|
```ruby
|
204
216
|
reynard.snake_cases({ "1st-class" => "first_class" })
|
@@ -218,6 +230,82 @@ Don't use this to map common property names that would work fine otherwise, beca
|
|
218
230
|
reynard.snake_cases({ "name" => "naem" })
|
219
231
|
```
|
220
232
|
|
233
|
+
### Optional properties
|
234
|
+
|
235
|
+
The current version of Reynard does not read or enforce the properties defined in the schema, instead it builds the response object based on the properties returned by the service. This was done deliberately to make it easier to access a server with a newer or older schema than the one used to build the Reynard instance.
|
236
|
+
|
237
|
+
In the code that means that you may have to check if you are receiving certain attributes, you can do this in a number of ways:
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
response.object.respond_to?(:name)
|
241
|
+
response.parsed_body["name"]
|
242
|
+
response.object["name"]
|
243
|
+
```
|
244
|
+
|
245
|
+
### Taking control of a model
|
246
|
+
|
247
|
+
As noted earlier there is a deterministic way in which Reynard decides on a model name. This means that you can define the model name before Reynard gets to it.
|
248
|
+
|
249
|
+
The easiest way to find out how Reynard does this, is to actually perform the operation and look at the response. Let's look at an example where Reynard creates a `Library` model:
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
response.object.class #=> Reynard::Models::Library
|
253
|
+
response.parsed_body #=> {"name" => "Alexandria"}
|
254
|
+
```
|
255
|
+
|
256
|
+
One way to ensure that the response object has the required attributes is to defined a `valid?` method on it:
|
257
|
+
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
class Reynard
|
261
|
+
module Models
|
262
|
+
class Library < Reynard::Model
|
263
|
+
def valid?
|
264
|
+
(%w[name] - @attributes.keys).empty?
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
```
|
270
|
+
|
271
|
+
Next time you perform a request you can use your version of `Library`:
|
272
|
+
|
273
|
+
```ruby
|
274
|
+
if response.object.valid?
|
275
|
+
puts "The library is valid!"
|
276
|
+
else
|
277
|
+
puts "The library is not valid :-( #{response.parsed_object.inspect}"
|
278
|
+
end
|
279
|
+
```
|
280
|
+
|
281
|
+
Another way to do this is to override the `attributes=` method.
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
def attributes=(attributes)
|
285
|
+
super # call super or nested attributes and other features will break
|
286
|
+
raise_invalid unless valid?
|
287
|
+
end
|
288
|
+
|
289
|
+
private
|
290
|
+
|
291
|
+
def raise_invalid
|
292
|
+
return if valid?
|
293
|
+
|
294
|
+
raise(
|
295
|
+
ArgumentError,
|
296
|
+
"Library may not be initialized without all required attributes."
|
297
|
+
)
|
298
|
+
end
|
299
|
+
```
|
300
|
+
|
301
|
+
A third way of dealing with optional attributes is to define an accessor yourself.
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
def name
|
305
|
+
@attributes.fetch("name") { "Unnnamed library" }
|
306
|
+
end
|
307
|
+
```
|
308
|
+
|
221
309
|
## Logging
|
222
310
|
|
223
311
|
When you want to know what the Reynard client is doing you can enable logging.
|
@@ -234,6 +322,19 @@ The logging should be compatible with the Ruby on Rails logger.
|
|
234
322
|
reynard.logger(Rails.logger).execute
|
235
323
|
```
|
236
324
|
|
325
|
+
## Headers
|
326
|
+
|
327
|
+
You can add request headers at any time to a Reynard context, these are additive so you can easily have global headers for all requests and specific ones for an operation.
|
328
|
+
|
329
|
+
```ruby
|
330
|
+
reynard = reynard.headers(
|
331
|
+
{
|
332
|
+
"User-Agent" => "MyApplication/12.1.1 Reynard/#{Reynard::VERSION}",
|
333
|
+
"Accept" => "application/json"
|
334
|
+
}
|
335
|
+
)
|
336
|
+
```
|
337
|
+
|
237
338
|
## Debugging
|
238
339
|
|
239
340
|
You can turn on debug logging in `Net::HTTP` by setting the `DEBUG` environment variable. After setting this, all HTTP interaction will be written to STDERR.
|
data/lib/reynard/model.rb
CHANGED
@@ -28,7 +28,11 @@ class Reynard
|
|
28
28
|
# Until we can set accessors based on the schema
|
29
29
|
def method_missing(attribute_name, *)
|
30
30
|
attribute_name = attribute_name.to_s
|
31
|
-
|
31
|
+
if @attributes.key?(attribute_name)
|
32
|
+
@attributes[attribute_name]
|
33
|
+
else
|
34
|
+
@attributes.fetch(@snake_cases.fetch(attribute_name))
|
35
|
+
end
|
32
36
|
rescue KeyError
|
33
37
|
raise NoMethodError, "undefined method `#{attribute_name}' for #{inspect}"
|
34
38
|
end
|
data/lib/reynard/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reynard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manfred Stienstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-07-
|
11
|
+
date: 2023-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|