api-blueprint 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d23a188a9076e091b9ce710bad84b2bafd27723
4
- data.tar.gz: e3cd015fb4cc6b563113515cb8a00f1387fe4345
3
+ metadata.gz: ec684c45d9e4a9a68fff3a249ccf2a55867fe871
4
+ data.tar.gz: a3d9ae3d1a9cb681122a854f8f71b6e1860d8cf7
5
5
  SHA512:
6
- metadata.gz: 4dd0313e92b043c835515e9e970313c79d452167604560de4a988cd7a9aee672629412e990a16fc9c783039eba73bc05e8b50df3e0e735ba41143164a12500dd
7
- data.tar.gz: 708aad91e765f722ad8c9fa34b47aa71887d92a3b04fa34a67564bb4d2fb1feecce368283e3e76c3cff47a95c8bd9db15179f70718ad9ddfe375f70f4ff8cb14
6
+ metadata.gz: 29850f1231fb34be81d8efcd579ca995741fe896ad2b0d91e4b9372c7c5d4d7e92e82d9b915bea884bafcb4b73fbbe879cb07f2c64481a7395e0158ad344516e
7
+ data.tar.gz: aceaf3b5c6ce9e8b052fd0968947042922701e8b05e6c29b8bea29205115ba7d4a8fa521b859c69406c9fe5692629170bf7830520ec0c5bee85beb3026b0968f
data/README.md CHANGED
@@ -99,6 +99,25 @@ config.replacements = {
99
99
  }
100
100
  ```
101
101
 
102
+ ## Validation
103
+
104
+ You can use [active model validations](http://guides.rubyonrails.org/active_record_validations.html) on models to validate body payloads. This is useful to pre-check user input before sending API requests. It is disabled by default, but to enable, you just need to set `validate: true` on your blueprint definitions:
105
+
106
+ ```ruby
107
+ class Astronaut < ApiBlueprint::Model
108
+ attribute :name, Types::String
109
+ validates :name, presence: true
110
+
111
+ def self.send_to_space(name)
112
+ blueprint :post, "/space", body: { name: name }, validate: true
113
+ end
114
+ end
115
+
116
+ Astronaut.send_to_space(nil) # => <ActiveModel::Errors ...>
117
+ ```
118
+
119
+ Behind the scenes, ApiBlueprint uses the body hash to initialize a new instance of your model, and then runs validations. If there are any errors, the API request is not run and the errors object is returned.
120
+
102
121
  ## Blueprint options
103
122
 
104
123
  When defining a blueprint in a model, you can pass it a number of options to set request headers, params, body, or to run code after an instance of the model has been initialized. Here's some examples:
@@ -4,6 +4,7 @@ require 'dry-initializer'
4
4
  require 'faraday'
5
5
  require 'faraday_middleware'
6
6
  require 'active_model'
7
+ require 'active_support/core_ext/hash'
7
8
  require 'addressable'
8
9
 
9
10
  require 'api-blueprint/cache'
@@ -18,4 +19,5 @@ require 'api-blueprint/collection'
18
19
 
19
20
  module ApiBlueprint
20
21
  class DefinitionError < StandardError; end
22
+ class BuilderError < StandardError; end
21
23
  end
@@ -24,17 +24,15 @@ module ApiBlueprint
24
24
  end
25
25
 
26
26
  def run(options = {}, runner = nil)
27
+ if options.delete :validate
28
+ result = build from: options[:body]
29
+ return result.errors if result.invalid?
30
+ end
31
+
27
32
  response = call_api all_request_options(options)
28
33
 
29
34
  if creates.present?
30
- builder_options = {
31
- body: parser.parse(response.body),
32
- headers: response.headers,
33
- replacements: replacements,
34
- creates: creates
35
- }
36
-
37
- created = builder.new(builder_options).build
35
+ created = build from: response.body, headers: response.headers
38
36
  else
39
37
  created = response
40
38
  end
@@ -44,6 +42,17 @@ module ApiBlueprint
44
42
 
45
43
  private
46
44
 
45
+ def build(from:, headers: {})
46
+ builder_options = {
47
+ body: parser.parse(from),
48
+ headers: headers,
49
+ replacements: replacements,
50
+ creates: creates
51
+ }
52
+
53
+ builder.new(builder_options).build
54
+ end
55
+
47
56
  def call_api(options)
48
57
  connection.send options[:http_method] do |req|
49
58
  req.url options[:url]
@@ -22,7 +22,11 @@ module ApiBlueprint
22
22
  end
23
23
 
24
24
  def build_item(item)
25
- creates.new item
25
+ if creates.present?
26
+ creates.new item
27
+ else
28
+ raise BuilderError, "To build an object, you must set #creates"
29
+ end
26
30
  end
27
31
 
28
32
  private
@@ -1,3 +1,3 @@
1
1
  module ApiBlueprint
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
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.1.1
4
+ version: 0.2.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-04-06 00:00:00.000000000 Z
11
+ date: 2018-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-types
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: addressable
112
+ name: activesupport
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -123,27 +123,13 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: rails
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: 5.1.5
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: 5.1.5
139
- - !ruby/object:Gem::Dependency
140
- name: sqlite3
126
+ name: addressable
141
127
  requirement: !ruby/object:Gem::Requirement
142
128
  requirements:
143
129
  - - ">="
144
130
  - !ruby/object:Gem::Version
145
131
  version: '0'
146
- type: :development
132
+ type: :runtime
147
133
  prerelease: false
148
134
  version_requirements: !ruby/object:Gem::Requirement
149
135
  requirements: