api-blueprint 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|