api-blueprint 0.5.0 → 0.6.0
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.
- checksums.yaml +4 -4
- data/README.md +47 -2
- data/lib/api-blueprint.rb +14 -4
- data/lib/api-blueprint/blueprint.rb +2 -4
- data/lib/api-blueprint/builder.rb +3 -4
- data/lib/api-blueprint/model.rb +2 -4
- data/lib/api-blueprint/response_middleware.rb +4 -8
- data/lib/api-blueprint/runner.rb +13 -0
- data/lib/api-blueprint/struct.rb +9 -0
- data/lib/api-blueprint/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc247d9616a2e34feda3dd467150f03d384628c0
|
4
|
+
data.tar.gz: 68106129bf5eccc56440c0d15ae49f40034c7b20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc963e572698777cded8128676784cbd2625c6b55f34931a274f7697d93bd57bf50e4ae91590a018841560472898aaf35400a00885e1e0929bfce59a0329c3ca
|
7
|
+
data.tar.gz: 05333cf34ddc87d344cfb5bd90bf8d37e94282b53a6d98114b8a67a04d99450e37dc2470a31aea443ba94b9c57e5eb2bcab17bec3d6beb2eaf6a7c75a00afe53
|
data/README.md
CHANGED
@@ -61,6 +61,51 @@ The result of using `api.run` on a blueprint is as you'd expect, nice model inst
|
|
61
61
|
</ul>
|
62
62
|
```
|
63
63
|
|
64
|
+
## Collections
|
65
|
+
|
66
|
+
Sometimes you might want a model which requires multiple api calls and collects the results onto different attributes. You can use an `ApiBlueprint::Model.collection` for this.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
class Vehicles < ApiBlueprint::Model
|
70
|
+
attribute :car, Types.Constructor(Car)
|
71
|
+
attribute :bus, Types.Constructor(Bus)
|
72
|
+
|
73
|
+
def self.fetch_all(color)
|
74
|
+
collection \
|
75
|
+
car: Car.all(color),
|
76
|
+
bus: Bus.all(color)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Example use
|
81
|
+
red_vehicles = api.run Vehicles.fetch_all("red")
|
82
|
+
red_vehicles.cars # [<Car>, <Car>, ...]
|
83
|
+
red_vehicles.busses # [<Bus>, <Bus>, ...]
|
84
|
+
```
|
85
|
+
|
86
|
+
## Request registry
|
87
|
+
|
88
|
+
If you use the same api request in multiple controllers, it can be cumbersome to remember to set the cache options and pass all required params to api calls. ApiBlueprint includes a registry, which can be used as a container to store blueprints along with cache options and make it quicker and simpler to re-use in controllers.
|
89
|
+
|
90
|
+
You can add to the registry when initialing the api runner, or later.
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
# Add `astronauts_in_space` to the registry when initializing the runner:
|
94
|
+
api = ApiBlueprint::Runner.new registry: {
|
95
|
+
astronauts_in_space: { blueprint: -> { AstronautsInSpace.fetch }, cache: { ttl: 10.minutes } }
|
96
|
+
}
|
97
|
+
|
98
|
+
# Add `vehicles` to the existing registry:
|
99
|
+
api.register :vehicles, -> { Vehicles.fetch_all }, ttl: 60.minutes
|
100
|
+
```
|
101
|
+
|
102
|
+
Once a blueprint is registered in the registry, you can invoke it via the key name on the runner:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
api.astronauts_in_space # the same as running api.run AstronautsInSpace.fetch, ttl: 10.minutes
|
106
|
+
api.vehicles # the same as running api.run Vehicles.fetch_all, ttl: 60.minutes
|
107
|
+
```
|
108
|
+
|
64
109
|
## Model Configuration
|
65
110
|
|
66
111
|
Using a `configure` block on models, you can define a default url (host), a [parser](#configparser), a [builder](#configbuilder) and can define a list of [replacements](#configreplacements):
|
@@ -126,10 +171,10 @@ Certain response statuses will also cause ApiBlueprint to behave in different wa
|
|
126
171
|
|
127
172
|
| HTTP Status range | Behavior |
|
128
173
|
| ----------------- | -------- |
|
129
|
-
| 200 -
|
174
|
+
| 200 - 400 | Objects are built normally, no errors raised |
|
130
175
|
| 401 | raises `ApiBlueprint::UnauthenticatedError` |
|
131
176
|
| 404 | raises `ApiBlueprint::NotFoundError` |
|
132
|
-
|
|
177
|
+
| 402 - 499 | raises `ApiBlueprint::ClientError` |
|
133
178
|
| 500 - 599 | raises `ApiBlueprint::ServerError` |
|
134
179
|
|
135
180
|
## Access to response headers and status codes
|
data/lib/api-blueprint.rb
CHANGED
@@ -7,6 +7,7 @@ require 'active_model'
|
|
7
7
|
require 'active_support/core_ext/hash'
|
8
8
|
require 'addressable'
|
9
9
|
|
10
|
+
require 'api-blueprint/struct'
|
10
11
|
require 'api-blueprint/response_middleware'
|
11
12
|
require 'api-blueprint/cache'
|
12
13
|
require 'api-blueprint/types'
|
@@ -19,10 +20,19 @@ require 'api-blueprint/runner'
|
|
19
20
|
require 'api-blueprint/collection'
|
20
21
|
|
21
22
|
module ApiBlueprint
|
23
|
+
class ResponseError < StandardError
|
24
|
+
attr_reader :status, :headers, :body
|
25
|
+
def initialize(env)
|
26
|
+
@status = env.status
|
27
|
+
@headers = env.response_headers.symbolize_keys
|
28
|
+
@body = env.body
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
22
32
|
class DefinitionError < StandardError; end
|
23
33
|
class BuilderError < StandardError; end
|
24
|
-
class ServerError <
|
25
|
-
class UnauthenticatedError <
|
26
|
-
class ClientError <
|
27
|
-
class NotFoundError <
|
34
|
+
class ServerError < ResponseError; end
|
35
|
+
class UnauthenticatedError < ResponseError; end
|
36
|
+
class ClientError < ResponseError; end
|
37
|
+
class NotFoundError < ResponseError; end
|
28
38
|
end
|
@@ -1,14 +1,12 @@
|
|
1
1
|
module ApiBlueprint
|
2
|
-
class Blueprint <
|
3
|
-
constructor_type :schema
|
4
|
-
|
2
|
+
class Blueprint < ApiBlueprint::Struct
|
5
3
|
attribute :http_method, Types::Symbol.default(:get).enum(*Faraday::Connection::METHODS)
|
6
4
|
attribute :url, Types::String
|
7
5
|
attribute :headers, Types::Hash.default(Hash.new)
|
8
6
|
attribute :params, Types::Hash.default(Hash.new)
|
9
7
|
attribute :body, Types::Hash.default(Hash.new)
|
10
8
|
attribute :creates, Types::Any
|
11
|
-
attribute :parser, Types.Instance(ApiBlueprint::Parser).default(ApiBlueprint::Parser.new)
|
9
|
+
attribute :parser, Types.Instance(ApiBlueprint::Parser).optional.default(ApiBlueprint::Parser.new)
|
12
10
|
attribute :replacements, Types::Hash.default(Hash.new)
|
13
11
|
attribute :after_build, Types::Instance(Proc).optional
|
14
12
|
attribute :builder, Types.Instance(ApiBlueprint::Builder).default(ApiBlueprint::Builder.new)
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module ApiBlueprint
|
2
|
-
class Builder <
|
3
|
-
constructor_type :schema
|
2
|
+
class Builder < ApiBlueprint::Struct
|
4
3
|
|
5
4
|
attribute :body, Types::Hash.default(Hash.new)
|
6
5
|
attribute :headers, Types::Hash.default(Hash.new)
|
7
|
-
attribute :status, Types::
|
6
|
+
attribute :status, Types::Integer.optional
|
8
7
|
attribute :replacements, Types::Hash.default(Hash.new)
|
9
|
-
attribute :creates, Types::Any
|
8
|
+
attribute :creates, Types::Any.optional
|
10
9
|
|
11
10
|
attr_writer :body
|
12
11
|
|
data/lib/api-blueprint/model.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module ApiBlueprint
|
2
|
-
class Model <
|
2
|
+
class Model < ApiBlueprint::Struct
|
3
3
|
extend Dry::Configurable
|
4
4
|
include ActiveModel::Conversion
|
5
5
|
include ActiveModel::Validations
|
@@ -7,15 +7,13 @@ module ApiBlueprint
|
|
7
7
|
extend ActiveModel::Naming
|
8
8
|
extend ActiveModel::Callbacks
|
9
9
|
|
10
|
-
constructor_type :schema
|
11
|
-
|
12
10
|
setting :host, ""
|
13
11
|
setting :parser, Parser.new
|
14
12
|
setting :builder, Builder.new
|
15
13
|
setting :replacements, {}
|
16
14
|
|
17
15
|
attribute :response_headers, Types::Hash.optional
|
18
|
-
attribute :response_status, Types::
|
16
|
+
attribute :response_status, Types::Integer.optional
|
19
17
|
|
20
18
|
def self.blueprint(http_method, url, options = {}, &block)
|
21
19
|
blueprint_opts = {
|
@@ -4,19 +4,15 @@ module ApiBlueprint
|
|
4
4
|
def on_complete(env)
|
5
5
|
case env[:status]
|
6
6
|
when 401
|
7
|
-
raise ApiBlueprint::UnauthenticatedError
|
7
|
+
raise ApiBlueprint::UnauthenticatedError.new(env)
|
8
8
|
when 404
|
9
|
-
raise ApiBlueprint::NotFoundError
|
9
|
+
raise ApiBlueprint::NotFoundError.new(env)
|
10
10
|
when 402..499
|
11
|
-
raise ApiBlueprint::ClientError
|
11
|
+
raise ApiBlueprint::ClientError.new(env)
|
12
12
|
when 500...599
|
13
|
-
raise ApiBlueprint::ServerError
|
13
|
+
raise ApiBlueprint::ServerError.new(env)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def response_values(env)
|
18
|
-
{ status: env.status, headers: env.response_headers, body: env.body }
|
19
|
-
end
|
20
|
-
|
21
17
|
end
|
22
18
|
end
|
data/lib/api-blueprint/runner.rb
CHANGED
@@ -4,6 +4,7 @@ module ApiBlueprint
|
|
4
4
|
|
5
5
|
option :headers, default: proc { {} }
|
6
6
|
option :cache, default: proc { Cache.new key: "global" }
|
7
|
+
option :registry, default: proc { {} }
|
7
8
|
|
8
9
|
def run(item, cache_options = {})
|
9
10
|
if item.is_a?(Blueprint)
|
@@ -19,6 +20,18 @@ module ApiBlueprint
|
|
19
20
|
{ headers: headers, cache: cache }
|
20
21
|
end
|
21
22
|
|
23
|
+
def register(name, blueprint, cache_options = {})
|
24
|
+
registry[name] = { blueprint: blueprint, cache: cache_options }
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_missing(name, *args, &block)
|
28
|
+
if stored_method = registry[name].presence
|
29
|
+
run stored_method[:blueprint].call(*args), stored_method[:cache]
|
30
|
+
else
|
31
|
+
raise NoMethodError, "#{name} is not defined in the ApiBlueprint::Runner registry"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
22
35
|
private
|
23
36
|
|
24
37
|
def run_blueprint(blueprint, cache_options)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api-blueprint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Damien Timewell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-types
|
@@ -212,6 +212,7 @@ files:
|
|
212
212
|
- lib/api-blueprint/parser.rb
|
213
213
|
- lib/api-blueprint/response_middleware.rb
|
214
214
|
- lib/api-blueprint/runner.rb
|
215
|
+
- lib/api-blueprint/struct.rb
|
215
216
|
- lib/api-blueprint/types.rb
|
216
217
|
- lib/api-blueprint/url.rb
|
217
218
|
- lib/api-blueprint/version.rb
|