request-builder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 457e80f8bbd15d0c31db2b9c22eb0cdad23d220263b046333e7f23233fd39f7c
4
+ data.tar.gz: b2631a86209e6e280069118793f8610360675ace8cc84841a091389220cb9c78
5
+ SHA512:
6
+ metadata.gz: fccbcdc8f74870d091a5d660ea44b76b400037570db2bfa1af2516fffa14a4f1ec49625785e65062da585eb36fc8d75bb62b6395f705da6a9fd68c5d06ac93d0
7
+ data.tar.gz: 8040052bf21eaa5c8693abccc82959d3739684cda46145ab2921d5fc09ed734a69ff57816057126163070d403bff2a9acb9907cf6b918a6ccc0941609225a4f5
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Request::Builder
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/request/builder`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'request-builder'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install request-builder
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/request-builder. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/request-builder/blob/master/CODE_OF_CONDUCT.md).
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
+
42
+ ## Code of Conduct
43
+
44
+ Everyone interacting in the Request::Builder project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/request-builder/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,19 @@
1
+ require "faraday"
2
+ require "faraday_middleware"
3
+
4
+ module Request
5
+ module Builder
6
+ module Connection
7
+ private
8
+
9
+ def connection
10
+ @_connection ||= Faraday.new(url: config.host) do |builder|
11
+ builder.adapter config.adapter, config.stubs
12
+ builder.request config.request_middleware
13
+ builder.response config.response_middleware
14
+ builder.response(:logger, config.logger, bodies: true) if config.logger
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module Request
2
+ module Builder
3
+ module Dsl
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base.class_eval do
7
+ def config
8
+ @config ||= self.class.config
9
+ end
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+ def config
15
+ @config ||= RequestConfig.new
16
+ end
17
+
18
+ def configure(conf = nil, &block)
19
+ @config = conf.dup if conf
20
+
21
+ config.instance_eval(&block) if block
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,37 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Base
4
+ include ValueWithContext
5
+
6
+ attr_accessor :context
7
+ attr_reader :store
8
+
9
+ delegate_missing_to :context
10
+
11
+ def initialize(context = nil)
12
+ @context = context
13
+ end
14
+
15
+ def each(&block)
16
+ raise NotImplementedError unless store.is_a?(Enumerable)
17
+
18
+ store.each do |value|
19
+ value[1] = value_with_context(value[1])
20
+ block.call(value)
21
+ end
22
+ end
23
+
24
+ def [] key
25
+ raise NotImplementedError unless store.is_a?(Enumerable)
26
+
27
+ value_with_context(store[key])
28
+ end
29
+
30
+ private
31
+
32
+ def store
33
+ raise NotImplementedError
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Body < Request::Builder::RequestConfig::Base
4
+ def set(&block)
5
+ raise ArgumentError, 'You must provide a block' unless block_given?
6
+
7
+ @store = block
8
+ end
9
+
10
+ def to_h
11
+ value_with_context(store)
12
+ end
13
+
14
+ private
15
+
16
+ def store
17
+ @store ||= nil
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Callbacks < Request::Builder::RequestConfig::Base
4
+ [:before_validate].each do |name|
5
+ define_method name do |&block|
6
+ raise ArgumentError, 'You must provide a block' unless block
7
+
8
+ store[name] = block
9
+ end
10
+ end
11
+
12
+ def each(&block)
13
+ store.each do |value|
14
+ block.call(value)
15
+ end
16
+ end
17
+
18
+ def [] key
19
+ store[key]
20
+ end
21
+
22
+ private
23
+
24
+ def store
25
+ @store ||= HashWithIndifferentAccess.new
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Headers < Request::Builder::RequestConfig::Base
4
+ def header(key, value = nil, &block)
5
+ raise ArgumentError, 'Must provide a value or block' if !value && !block
6
+
7
+ store[key] = block || value
8
+ end
9
+
10
+ private
11
+
12
+ def store
13
+ @store ||= HashWithIndifferentAccess.new
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig::Params < Request::Builder::RequestConfig::Base
4
+ def param(key, value = nil, &block)
5
+ raise ArgumentError, 'Must provide a value or block' if !value && !block
6
+
7
+ store[key] = block || value
8
+ end
9
+
10
+ private
11
+
12
+ def store
13
+ @store ||= HashWithIndifferentAccess.new
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,111 @@
1
+ module Request
2
+ module Builder
3
+ class RequestConfig
4
+ include ValueWithContext
5
+
6
+ delegate_missing_to :context
7
+
8
+ attrs = [:host, :path, :method, :request_middleware, :response_middleware, :adapter, :logger, :timeout]
9
+
10
+ attr_reader :context, :body_conf, :headers_conf, :params_conf, :callbacks_conf, :stubs
11
+ attr_writer *attrs, :stubs
12
+
13
+ alias callbacks callbacks_conf
14
+
15
+ def initialize
16
+ @host = nil
17
+ @path = '/'
18
+ @method = :get
19
+ @request_middleware = :json
20
+ @response_middleware = :json
21
+ @adapter = :net_http
22
+ @stubs = Faraday::Adapter::Test::Stubs.new
23
+ @logger = nil
24
+ @timeout = 30
25
+ @body_conf = RequestConfig::Body.new
26
+ @headers_conf = RequestConfig::Headers.new
27
+ @params_conf = RequestConfig::Params.new
28
+ @callbacks_conf = RequestConfig::Callbacks.new
29
+ @response_schema = Dry::Schema.Params
30
+ end
31
+
32
+ attrs.each do |attr|
33
+ define_method attr do |value = nil, &block|
34
+ if value.nil? && block.nil?
35
+ value_with_context(instance_variable_get("@#{attr}"))
36
+ else
37
+ instance_variable_set("@#{attr}", block || value)
38
+ end
39
+ end
40
+ end
41
+
42
+ [:before_validate].each do |name|
43
+ define_method name do |&block|
44
+ callbacks.send(name, &block)
45
+ end
46
+ end
47
+
48
+ def stubs(value = nil, &block)
49
+ if block_given?
50
+ @stubs.instance_eval(&block)
51
+ elsif value
52
+ @stubs = value
53
+ else
54
+ @stubs
55
+ end
56
+ end
57
+
58
+ def schema(value = nil, &block)
59
+ if block_given?
60
+ @response_schema = Dry::Schema.Params(&block)
61
+ elsif value
62
+ @response_schema = value
63
+ else
64
+ @response_schema
65
+ end
66
+ end
67
+
68
+ def body(&block)
69
+ return body_conf.set(&block) if block_given?
70
+
71
+ body_conf.to_h
72
+ end
73
+
74
+ def headers(&block)
75
+ headers_conf.instance_eval(&block) if block_given?
76
+
77
+ headers_conf
78
+ end
79
+
80
+ def header(key, value = nil, &block)
81
+ headers_conf.header(key, value, &block)
82
+ end
83
+
84
+ def params(&block)
85
+ params_conf.instance_eval(&block) if block_given?
86
+
87
+ params_conf
88
+ end
89
+
90
+ def param(key, value = nil, &block)
91
+ params_conf.param(key, value, &block)
92
+ end
93
+
94
+ def context=(context)
95
+ @context = context
96
+
97
+ [body_conf, headers_conf, params_conf, callbacks_conf].each { |cnf| cnf.context = context }
98
+ end
99
+
100
+ def [] property
101
+ instance_variable_get("@#{property}".to_sym)
102
+ end
103
+
104
+ Module.new do
105
+ singleton_class.send :define_method, :included do |host_class|
106
+ host_class.extend class_methods
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,35 @@
1
+ module Request
2
+ module Builder
3
+ class Result
4
+ attr_reader :response, :context, :body
5
+
6
+ delegate :headers, :status, to: :response
7
+ delegate :config, to: :context
8
+ delegate :schema, to: :config
9
+ delegate :errors, to: :schema_result
10
+
11
+ def initialize(response, context)
12
+ @response = response
13
+ @context = context
14
+ @before_validate = config.callbacks[:before_validate]
15
+ @body = @before_validate ? @before_validate.call(response.body.to_h) : response.body.to_h
16
+ end
17
+
18
+ def success?
19
+ status == 200 && schema_result.success?
20
+ end
21
+
22
+ def failure?
23
+ !success?
24
+ end
25
+
26
+ def schema_result
27
+ @schema_result ||= schema.call(body)
28
+ end
29
+
30
+ def full_errors
31
+ errors(full: true).to_h
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module Request
2
+ module Builder
3
+ module ValueWithContext
4
+ def value_with_context(obj)
5
+ return obj unless obj.is_a?(Proc)
6
+
7
+ case obj.arity
8
+ when 1, -1, -2 then instance_exec(@context, &obj)
9
+ else instance_exec(&obj)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ module Request
2
+ module Builder
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,77 @@
1
+
2
+ require "dry-initializer"
3
+ require "dry-schema"
4
+ require "active_support/hash_with_indifferent_access"
5
+ require "active_support/core_ext/module/delegation"
6
+ require_relative "builder/version"
7
+ require_relative "builder/value_with_context"
8
+ require_relative "builder/request_config"
9
+ require_relative "builder/request_config/base"
10
+ require_relative "builder/request_config/body"
11
+ require_relative "builder/request_config/params"
12
+ require_relative "builder/request_config/headers"
13
+ require_relative "builder/request_config/callbacks"
14
+ require_relative "builder/result"
15
+ require_relative "builder/dsl"
16
+ require_relative "builder/connection"
17
+
18
+ module Request
19
+ module Builder
20
+ def self.included(base)
21
+ base.extend ClassMethods
22
+ base.extend Dry::Initializer
23
+ base.include Request::Builder::Dsl
24
+ base.include Request::Builder::Connection
25
+
26
+ class << base
27
+ alias_method :__new, :new
28
+ def new(*args)
29
+ e = __new(*args)
30
+ e.send(:set_config_context)
31
+ e
32
+ end
33
+ end
34
+ end
35
+
36
+ module ClassMethods
37
+ def call(**args)
38
+ new(**args).call
39
+ end
40
+ alias perform call
41
+ end
42
+
43
+ def call
44
+ do_request
45
+ result
46
+ end
47
+ alias perform call
48
+
49
+ private
50
+
51
+ attr_reader :response
52
+
53
+ def result
54
+ @result ||= Result.new(response, self)
55
+ end
56
+
57
+ def do_request
58
+ @response = connection.send(config.method.downcase, config.path) do |req|
59
+ req.options.timeout = config.timeout
60
+
61
+ config.params.each do |key, value|
62
+ req.params[key] = value
63
+ end
64
+
65
+ config.headers.each do |key, value|
66
+ req.headers[key] = value
67
+ end
68
+
69
+ req.body = config.body
70
+ end
71
+ end
72
+
73
+ def set_config_context
74
+ config.context = self
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "request/builder"
@@ -0,0 +1,35 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require_relative 'lib/request/builder/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "request-builder"
8
+ spec.version = Request::Builder::VERSION.dup
9
+ spec.authors = ["Anton Kostyuk"]
10
+ spec.email = ["anton.kostuk.2012@gmail.com"]
11
+
12
+ spec.summary = %q{Request DSL}
13
+ spec.description = %q{Request DSL}
14
+ spec.homepage = "https://github.com/RainbowPonny/request-builder"
15
+ spec.license = "MIT"
16
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/RainbowPonny/request-builder"
20
+
21
+ spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "request-builder.gemspec", "lib/**/*"]
22
+ spec.bindir = "bin"
23
+ spec.executables = []
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_dependency "faraday", "~> 1.7.1"
27
+ spec.add_dependency "faraday_middleware", "~> 1.2.0"
28
+ spec.add_dependency "dry-schema", "~> 1.9"
29
+ spec.add_dependency "dry-initializer", "~> 3.0"
30
+
31
+ spec.add_runtime_dependency 'activesupport', ">= 5.0.0", "< 7.1.0"
32
+
33
+ spec.add_development_dependency "ffaker", "~> 2.21"
34
+ spec.add_development_dependency "rspec", "~> 3.0"
35
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: request-builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Anton Kostyuk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-09-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.7.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.7.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.2.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-schema
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.9'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dry-initializer
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 5.0.0
76
+ - - "<"
77
+ - !ruby/object:Gem::Version
78
+ version: 7.1.0
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: 5.0.0
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: 7.1.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: ffaker
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.21'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.21'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rspec
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '3.0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '3.0'
117
+ description: Request DSL
118
+ email:
119
+ - anton.kostuk.2012@gmail.com
120
+ executables: []
121
+ extensions: []
122
+ extra_rdoc_files: []
123
+ files:
124
+ - README.md
125
+ - lib/request-builder.rb
126
+ - lib/request/builder.rb
127
+ - lib/request/builder/connection.rb
128
+ - lib/request/builder/dsl.rb
129
+ - lib/request/builder/request_config.rb
130
+ - lib/request/builder/request_config/base.rb
131
+ - lib/request/builder/request_config/body.rb
132
+ - lib/request/builder/request_config/callbacks.rb
133
+ - lib/request/builder/request_config/headers.rb
134
+ - lib/request/builder/request_config/params.rb
135
+ - lib/request/builder/result.rb
136
+ - lib/request/builder/value_with_context.rb
137
+ - lib/request/builder/version.rb
138
+ - request-builder.gemspec
139
+ homepage: https://github.com/RainbowPonny/request-builder
140
+ licenses:
141
+ - MIT
142
+ metadata:
143
+ homepage_uri: https://github.com/RainbowPonny/request-builder
144
+ source_code_uri: https://github.com/RainbowPonny/request-builder
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: 2.3.0
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubygems_version: 3.1.6
161
+ signing_key:
162
+ specification_version: 4
163
+ summary: Request DSL
164
+ test_files: []