shark-on-lambda 0.6.10 → 1.0.0.rc1
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/.github/workflows/push-gem.yml +67 -0
- data/.github/workflows/tests.yml +32 -0
- data/README.md +10 -12
- data/changelog.md +11 -0
- data/gems.locked +73 -23
- data/lib/shark_on_lambda/api_gateway_handler.rb +61 -0
- data/lib/shark_on_lambda/application.rb +17 -0
- data/lib/shark_on_lambda/base_controller.rb +50 -0
- data/lib/shark_on_lambda/configuration.rb +9 -1
- data/lib/shark_on_lambda/dispatcher.rb +26 -0
- data/lib/shark_on_lambda/errors/base.rb +47 -0
- data/lib/shark_on_lambda/errors/base_serializer.rb +18 -0
- data/lib/shark_on_lambda/jsonapi_controller.rb +29 -0
- data/lib/shark_on_lambda/jsonapi_parameters.rb +66 -0
- data/lib/shark_on_lambda/jsonapi_renderer.rb +115 -0
- data/lib/shark_on_lambda/middleware/base.rb +23 -0
- data/lib/shark_on_lambda/middleware/jsonapi_rescuer.rb +31 -0
- data/lib/shark_on_lambda/middleware/rescuer.rb +38 -0
- data/lib/shark_on_lambda/query.rb +67 -0
- data/lib/shark_on_lambda/rack_adapters/api_gateway.rb +127 -0
- data/lib/shark_on_lambda/request.rb +9 -0
- data/lib/shark_on_lambda/response.rb +6 -0
- data/lib/shark_on_lambda/rspec/env_builder.rb +64 -0
- data/lib/shark_on_lambda/rspec/helpers.rb +84 -0
- data/lib/shark_on_lambda/rspec/jsonapi_helpers.rb +27 -0
- data/lib/shark_on_lambda/version.rb +1 -1
- data/lib/shark_on_lambda.rb +25 -28
- data/shark-on-lambda.gemspec +8 -3
- metadata +104 -24
- data/.gitlab-ci.yml +0 -39
- data/.travis.yml +0 -14
- data/lib/shark_on_lambda/api_gateway/base_controller.rb +0 -76
- data/lib/shark_on_lambda/api_gateway/base_handler.rb +0 -82
- data/lib/shark_on_lambda/api_gateway/concerns/http_response_validation.rb +0 -61
- data/lib/shark_on_lambda/api_gateway/errors.rb +0 -49
- data/lib/shark_on_lambda/api_gateway/headers.rb +0 -37
- data/lib/shark_on_lambda/api_gateway/jsonapi_controller.rb +0 -77
- data/lib/shark_on_lambda/api_gateway/jsonapi_parameters.rb +0 -68
- data/lib/shark_on_lambda/api_gateway/jsonapi_renderer.rb +0 -105
- data/lib/shark_on_lambda/api_gateway/parameters.rb +0 -18
- data/lib/shark_on_lambda/api_gateway/query.rb +0 -69
- data/lib/shark_on_lambda/api_gateway/request.rb +0 -148
- data/lib/shark_on_lambda/api_gateway/response.rb +0 -82
- data/lib/shark_on_lambda/api_gateway/serializers/base_error_serializer.rb +0 -20
- data/lib/shark_on_lambda/concerns/filter_actions.rb +0 -93
- data/lib/shark_on_lambda/tasks/build.rake +0 -146
- data/lib/shark_on_lambda/tasks.rb +0 -3
data/lib/shark_on_lambda.rb
CHANGED
@@ -1,51 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'pry' if Gem.loaded_specs.key?('pry')
|
4
|
+
|
3
5
|
require 'forwardable'
|
4
6
|
require 'ostruct'
|
5
7
|
require 'pathname'
|
6
8
|
require 'singleton'
|
7
9
|
|
10
|
+
require 'action_controller'
|
11
|
+
require 'action_dispatch'
|
12
|
+
require 'action_view'
|
8
13
|
require 'active_support/all'
|
9
14
|
require 'jsonapi/deserializable'
|
10
15
|
require 'jsonapi/serializable'
|
11
16
|
require 'rack/utils'
|
12
17
|
require 'yaml'
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
require 'shark_on_lambda/api_gateway/concerns/http_response_validation'
|
28
|
-
require 'shark_on_lambda/api_gateway/base_controller'
|
29
|
-
require 'shark_on_lambda/api_gateway/base_handler'
|
30
|
-
require 'shark_on_lambda/api_gateway/errors'
|
31
|
-
require 'shark_on_lambda/api_gateway/headers'
|
32
|
-
require 'shark_on_lambda/api_gateway/jsonapi_controller'
|
33
|
-
require 'shark_on_lambda/api_gateway/jsonapi_parameters'
|
34
|
-
require 'shark_on_lambda/api_gateway/jsonapi_renderer'
|
35
|
-
require 'shark_on_lambda/api_gateway/parameters'
|
36
|
-
require 'shark_on_lambda/api_gateway/query'
|
37
|
-
require 'shark_on_lambda/api_gateway/request'
|
38
|
-
require 'shark_on_lambda/api_gateway/response'
|
18
|
+
require 'zeitwerk'
|
19
|
+
|
20
|
+
# Without this, Zeitwerk hiccups in certain cases...
|
21
|
+
module SharkOnLambda; end
|
22
|
+
|
23
|
+
Zeitwerk::Loader.for_gem.tap do |loader|
|
24
|
+
loader.ignore(File.expand_path('shark-on-lambda.rb', __dir__))
|
25
|
+
loader.inflector.inflect(
|
26
|
+
'rspec' => 'RSpec',
|
27
|
+
'version' => 'VERSION'
|
28
|
+
)
|
29
|
+
loader.setup
|
30
|
+
loader.eager_load
|
31
|
+
end
|
39
32
|
|
40
33
|
# Top-level module for this gem.
|
41
34
|
module SharkOnLambda
|
42
35
|
class << self
|
43
|
-
extend
|
36
|
+
extend Forwardable
|
44
37
|
|
45
38
|
attr_writer :logger
|
46
39
|
|
47
40
|
def_instance_delegators :config, :root, :stage
|
48
41
|
|
42
|
+
def application
|
43
|
+
@application ||= Application.new
|
44
|
+
end
|
45
|
+
|
49
46
|
def config
|
50
47
|
Configuration.instance
|
51
48
|
end
|
@@ -72,7 +69,7 @@ module SharkOnLambda
|
|
72
69
|
end
|
73
70
|
|
74
71
|
def logger
|
75
|
-
@logger ||=
|
72
|
+
@logger ||= Logger.new(STDOUT)
|
76
73
|
end
|
77
74
|
|
78
75
|
def reset_configuration
|
data/shark-on-lambda.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.description = '`shark-on-lambda` does the heavy lifting for writing ' \
|
16
16
|
'web services based on AWS API Gateway on AWS Lambda ' \
|
17
17
|
'using Ruby.'
|
18
|
-
spec.homepage = 'https://
|
18
|
+
spec.homepage = 'https://github.com/Skudo/shark-on-lambda'
|
19
19
|
spec.license = 'MIT'
|
20
20
|
|
21
21
|
# Specify which files should be added to the gem when it is released.
|
@@ -30,15 +30,20 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
31
|
spec.require_paths = ['lib']
|
32
32
|
|
33
|
+
spec.add_dependency 'actionpack'
|
33
34
|
spec.add_dependency 'activesupport'
|
34
35
|
spec.add_dependency 'jsonapi-rb'
|
35
|
-
spec.add_dependency 'rack', '>= 2.0.8'
|
36
|
+
spec.add_dependency 'rack', '>= 2.0.8', '< 3'
|
37
|
+
spec.add_dependency 'zeitwerk', '~> 2.2'
|
36
38
|
|
37
39
|
# TODO: Do we really need `activemodel`?
|
38
|
-
# Or can we get away with mocking out
|
40
|
+
# Or can we get away with mocking out ActiveModel::Errors?
|
39
41
|
spec.add_development_dependency 'activemodel'
|
40
42
|
spec.add_development_dependency 'bundler'
|
41
43
|
spec.add_development_dependency 'factory_bot'
|
44
|
+
spec.add_development_dependency 'fasterer'
|
45
|
+
spec.add_development_dependency 'pry'
|
46
|
+
spec.add_development_dependency 'pry-byebug'
|
42
47
|
spec.add_development_dependency 'rake'
|
43
48
|
spec.add_development_dependency 'rspec'
|
44
49
|
spec.add_development_dependency 'rubocop'
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shark-on-lambda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Huy Dinh
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: actionpack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: activesupport
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,6 +59,9 @@ dependencies:
|
|
45
59
|
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: 2.0.8
|
62
|
+
- - "<"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '3'
|
48
65
|
type: :runtime
|
49
66
|
prerelease: false
|
50
67
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -52,6 +69,23 @@ dependencies:
|
|
52
69
|
- - ">="
|
53
70
|
- !ruby/object:Gem::Version
|
54
71
|
version: 2.0.8
|
72
|
+
- - "<"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: zeitwerk
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '2.2'
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '2.2'
|
55
89
|
- !ruby/object:Gem::Dependency
|
56
90
|
name: activemodel
|
57
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +128,48 @@ dependencies:
|
|
94
128
|
- - ">="
|
95
129
|
- !ruby/object:Gem::Version
|
96
130
|
version: '0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: fasterer
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: pry
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: pry-byebug
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
97
173
|
- !ruby/object:Gem::Dependency
|
98
174
|
name: rake
|
99
175
|
requirement: !ruby/object:Gem::Requirement
|
@@ -172,11 +248,11 @@ executables: []
|
|
172
248
|
extensions: []
|
173
249
|
extra_rdoc_files: []
|
174
250
|
files:
|
251
|
+
- ".github/workflows/push-gem.yml"
|
252
|
+
- ".github/workflows/tests.yml"
|
175
253
|
- ".gitignore"
|
176
|
-
- ".gitlab-ci.yml"
|
177
254
|
- ".rspec"
|
178
255
|
- ".rubocop.yml"
|
179
|
-
- ".travis.yml"
|
180
256
|
- CODE_OF_CONDUCT.md
|
181
257
|
- LICENSE.txt
|
182
258
|
- README.md
|
@@ -188,31 +264,34 @@ files:
|
|
188
264
|
- gems.rb
|
189
265
|
- lib/shark-on-lambda.rb
|
190
266
|
- lib/shark_on_lambda.rb
|
191
|
-
- lib/shark_on_lambda/
|
192
|
-
- lib/shark_on_lambda/
|
193
|
-
- lib/shark_on_lambda/
|
194
|
-
- lib/shark_on_lambda/api_gateway/errors.rb
|
195
|
-
- lib/shark_on_lambda/api_gateway/headers.rb
|
196
|
-
- lib/shark_on_lambda/api_gateway/jsonapi_controller.rb
|
197
|
-
- lib/shark_on_lambda/api_gateway/jsonapi_parameters.rb
|
198
|
-
- lib/shark_on_lambda/api_gateway/jsonapi_renderer.rb
|
199
|
-
- lib/shark_on_lambda/api_gateway/parameters.rb
|
200
|
-
- lib/shark_on_lambda/api_gateway/query.rb
|
201
|
-
- lib/shark_on_lambda/api_gateway/request.rb
|
202
|
-
- lib/shark_on_lambda/api_gateway/response.rb
|
203
|
-
- lib/shark_on_lambda/api_gateway/serializers/base_error_serializer.rb
|
204
|
-
- lib/shark_on_lambda/concerns/filter_actions.rb
|
267
|
+
- lib/shark_on_lambda/api_gateway_handler.rb
|
268
|
+
- lib/shark_on_lambda/application.rb
|
269
|
+
- lib/shark_on_lambda/base_controller.rb
|
205
270
|
- lib/shark_on_lambda/concerns/resettable_singleton.rb
|
206
271
|
- lib/shark_on_lambda/concerns/yaml_config_loader.rb
|
207
272
|
- lib/shark_on_lambda/configuration.rb
|
273
|
+
- lib/shark_on_lambda/dispatcher.rb
|
274
|
+
- lib/shark_on_lambda/errors/base.rb
|
275
|
+
- lib/shark_on_lambda/errors/base_serializer.rb
|
208
276
|
- lib/shark_on_lambda/inferrers/name_inferrer.rb
|
209
277
|
- lib/shark_on_lambda/inferrers/serializer_inferrer.rb
|
278
|
+
- lib/shark_on_lambda/jsonapi_controller.rb
|
279
|
+
- lib/shark_on_lambda/jsonapi_parameters.rb
|
280
|
+
- lib/shark_on_lambda/jsonapi_renderer.rb
|
281
|
+
- lib/shark_on_lambda/middleware/base.rb
|
282
|
+
- lib/shark_on_lambda/middleware/jsonapi_rescuer.rb
|
283
|
+
- lib/shark_on_lambda/middleware/rescuer.rb
|
284
|
+
- lib/shark_on_lambda/query.rb
|
285
|
+
- lib/shark_on_lambda/rack_adapters/api_gateway.rb
|
286
|
+
- lib/shark_on_lambda/request.rb
|
287
|
+
- lib/shark_on_lambda/response.rb
|
288
|
+
- lib/shark_on_lambda/rspec/env_builder.rb
|
289
|
+
- lib/shark_on_lambda/rspec/helpers.rb
|
290
|
+
- lib/shark_on_lambda/rspec/jsonapi_helpers.rb
|
210
291
|
- lib/shark_on_lambda/secrets.rb
|
211
|
-
- lib/shark_on_lambda/tasks.rb
|
212
|
-
- lib/shark_on_lambda/tasks/build.rake
|
213
292
|
- lib/shark_on_lambda/version.rb
|
214
293
|
- shark-on-lambda.gemspec
|
215
|
-
homepage: https://
|
294
|
+
homepage: https://github.com/Skudo/shark-on-lambda
|
216
295
|
licenses:
|
217
296
|
- MIT
|
218
297
|
metadata: {}
|
@@ -227,11 +306,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
227
306
|
version: '0'
|
228
307
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
229
308
|
requirements:
|
230
|
-
- - "
|
309
|
+
- - ">"
|
231
310
|
- !ruby/object:Gem::Version
|
232
|
-
version:
|
311
|
+
version: 1.3.1
|
233
312
|
requirements: []
|
234
|
-
|
313
|
+
rubyforge_project:
|
314
|
+
rubygems_version: 2.7.6.2
|
235
315
|
signing_key:
|
236
316
|
specification_version: 4
|
237
317
|
summary: Write beautiful Ruby applications for AWS Lambda
|
data/.gitlab-ci.yml
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
image: ruby:2.5
|
2
|
-
|
3
|
-
rspec:
|
4
|
-
script:
|
5
|
-
- gem install bundler
|
6
|
-
- bundle install
|
7
|
-
- bundle exec rake spec
|
8
|
-
|
9
|
-
rubocop:
|
10
|
-
script:
|
11
|
-
- gem install bundler
|
12
|
-
- bundle install
|
13
|
-
- bundle exec rubocop
|
14
|
-
|
15
|
-
package-to-github:
|
16
|
-
stage: deploy
|
17
|
-
script:
|
18
|
-
- mkdir ~/.gem
|
19
|
-
- 'echo ":github: Bearer $GH_PACKAGE_REGISTRY_KEY" > ~/.gem/credentials'
|
20
|
-
- chmod 0600 ~/.gem/credentials
|
21
|
-
- gem install bundler
|
22
|
-
- bundle install
|
23
|
-
- bundle exec rake build
|
24
|
-
- 'gem push --key github --host https://rubygems.pkg.github.com/Skudo pkg/`ls -1t pkg | head -1`'
|
25
|
-
only:
|
26
|
-
- tags
|
27
|
-
|
28
|
-
package-to-rubygems:
|
29
|
-
stage: deploy
|
30
|
-
script:
|
31
|
-
- mkdir ~/.gem
|
32
|
-
- 'echo ":rubygems_api_key: $RUBYGEMS_KEY" > ~/.gem/credentials'
|
33
|
-
- chmod 0600 ~/.gem/credentials
|
34
|
-
- gem install bundler
|
35
|
-
- bundle install
|
36
|
-
- bundle exec rake build
|
37
|
-
- 'gem push pkg/`ls -1t pkg | head -1`'
|
38
|
-
only:
|
39
|
-
- tags
|
data/.travis.yml
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SharkOnLambda
|
4
|
-
module ApiGateway
|
5
|
-
class BaseController
|
6
|
-
include SharkOnLambda::Concerns::FilterActions
|
7
|
-
include Concerns::HttpResponseValidation
|
8
|
-
|
9
|
-
attr_reader :action_name, :event, :context
|
10
|
-
|
11
|
-
def initialize(event:, context:)
|
12
|
-
@event = event
|
13
|
-
@context = context
|
14
|
-
end
|
15
|
-
|
16
|
-
def call(method)
|
17
|
-
@action_name = method.to_s
|
18
|
-
call_with_filter_actions(method)
|
19
|
-
response.to_h
|
20
|
-
end
|
21
|
-
|
22
|
-
def params
|
23
|
-
@params ||= Parameters.new(request)
|
24
|
-
end
|
25
|
-
|
26
|
-
def redirect_to(url, status: 307, message: nil)
|
27
|
-
status = status.to_i
|
28
|
-
validate_url!(url)
|
29
|
-
validate_redirection_status!(status)
|
30
|
-
|
31
|
-
uri = URI.parse(url)
|
32
|
-
response.set_header('Location', uri.to_s)
|
33
|
-
body = message.presence || "You are being redirected to: #{url}"
|
34
|
-
|
35
|
-
render(body, status: status)
|
36
|
-
end
|
37
|
-
|
38
|
-
def render(object, status: 200)
|
39
|
-
update_response(status: status, body: object)
|
40
|
-
respond!
|
41
|
-
end
|
42
|
-
|
43
|
-
def request
|
44
|
-
@request ||= Request.new(event: event, context: context)
|
45
|
-
end
|
46
|
-
|
47
|
-
def response
|
48
|
-
@response ||= Response.new
|
49
|
-
end
|
50
|
-
|
51
|
-
protected
|
52
|
-
|
53
|
-
def respond!
|
54
|
-
if responded?
|
55
|
-
raise Errors[500],
|
56
|
-
'#render or #redirect_to was called more than once.'
|
57
|
-
end
|
58
|
-
|
59
|
-
@responded = true
|
60
|
-
response
|
61
|
-
end
|
62
|
-
|
63
|
-
def responded?
|
64
|
-
@responded.present?
|
65
|
-
end
|
66
|
-
|
67
|
-
def update_response(status:, body: nil)
|
68
|
-
status = status.to_i
|
69
|
-
validate_response_status!(status)
|
70
|
-
|
71
|
-
response.status = status
|
72
|
-
response.body = body.to_s.presence
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SharkOnLambda
|
4
|
-
module ApiGateway
|
5
|
-
class BaseHandler
|
6
|
-
class << self
|
7
|
-
attr_writer :controller_class
|
8
|
-
|
9
|
-
def controller_class
|
10
|
-
return @controller_class if defined?(@controller_class)
|
11
|
-
|
12
|
-
name_inferrer = Inferrers::NameInferrer.from_handler_name(name)
|
13
|
-
controller_class_name = name_inferrer.controller
|
14
|
-
@controller_class = controller_class_name.safe_constantize
|
15
|
-
end
|
16
|
-
|
17
|
-
protected
|
18
|
-
|
19
|
-
def known_actions
|
20
|
-
controller_class.public_instance_methods(false)
|
21
|
-
end
|
22
|
-
|
23
|
-
def method_missing(name, *args, &block)
|
24
|
-
return super unless respond_to_missing?(name)
|
25
|
-
|
26
|
-
instance = new
|
27
|
-
instance.call(name, *args, &block)
|
28
|
-
end
|
29
|
-
|
30
|
-
def respond_to_missing?(name, _include_all = false)
|
31
|
-
known_actions.include?(name)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def call(action, event:, context:)
|
36
|
-
controller_class = self.class.controller_class
|
37
|
-
controller = controller_class.new(event: event, context: context)
|
38
|
-
controller.call(action)
|
39
|
-
rescue StandardError => e
|
40
|
-
handle_error(e)
|
41
|
-
end
|
42
|
-
|
43
|
-
protected
|
44
|
-
|
45
|
-
def client_error?(error)
|
46
|
-
error.is_a?(Errors::Base) && (400..499).cover?(error.status)
|
47
|
-
end
|
48
|
-
|
49
|
-
def error_body(status, message)
|
50
|
-
{
|
51
|
-
errors: [{
|
52
|
-
status: status.to_s,
|
53
|
-
title: ::Rack::Utils::HTTP_STATUS_CODES[status],
|
54
|
-
detail: message
|
55
|
-
}]
|
56
|
-
}.to_json
|
57
|
-
end
|
58
|
-
|
59
|
-
def error_response(error)
|
60
|
-
status = error.try(:status) || 500
|
61
|
-
|
62
|
-
{
|
63
|
-
statusCode: status,
|
64
|
-
headers: {
|
65
|
-
'Content-Type' => 'application/vnd.api+json'
|
66
|
-
},
|
67
|
-
body: error_body(status, error.message)
|
68
|
-
}
|
69
|
-
end
|
70
|
-
|
71
|
-
def handle_error(error)
|
72
|
-
unless client_error?(error)
|
73
|
-
SharkOnLambda.logger.error(error.message)
|
74
|
-
SharkOnLambda.logger.error(error.backtrace.join("\n"))
|
75
|
-
::Honeybadger.notify(error) if defined?(::Honeybadger)
|
76
|
-
end
|
77
|
-
|
78
|
-
error_response(error)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SharkOnLambda
|
4
|
-
module ApiGateway
|
5
|
-
module Concerns
|
6
|
-
# Provides methods for HTTP-related validation, e. g. for status codes
|
7
|
-
# and URIs. If validation fails, question mark methods return *false*,
|
8
|
-
# exclamation mark methods raise an exception.
|
9
|
-
#
|
10
|
-
# TODO: Specs for this module.
|
11
|
-
module HttpResponseValidation
|
12
|
-
# Validates a URL.
|
13
|
-
#
|
14
|
-
# @param url [String] The URL to validate.
|
15
|
-
# @return [TrueClass] If the URL is valid and present.
|
16
|
-
# @return [FalseClass] If the URL is invalid or blank.
|
17
|
-
def valid_url?(url)
|
18
|
-
URI.parse(url.to_s)
|
19
|
-
url.present?
|
20
|
-
rescue URI::InvalidURIError
|
21
|
-
false
|
22
|
-
end
|
23
|
-
|
24
|
-
# Validates a HTTP redirection status code.
|
25
|
-
#
|
26
|
-
# @param status [Number] The HTTP status code to validate.
|
27
|
-
# @return [NilClass] Returns *nil* if *status* is valid.
|
28
|
-
# @raise [Errors::InternalServerError] If the status code does not
|
29
|
-
# represent a HTTP redirection.
|
30
|
-
def validate_redirection_status!(status)
|
31
|
-
validate_response_status!(status)
|
32
|
-
return if (300..399).cover?(status)
|
33
|
-
|
34
|
-
raise Errors[500], 'HTTP redirections must have a 3xx status code.'
|
35
|
-
end
|
36
|
-
|
37
|
-
# Validates a HTTP status code.
|
38
|
-
#
|
39
|
-
# @param status [Number] The HTTP status code to validate.
|
40
|
-
# @return [NilClass] Returns *nil* if *status* is valid.
|
41
|
-
# @raise [Errors::InternalServerError] If the status code is unknown.
|
42
|
-
def validate_response_status!(status)
|
43
|
-
return if ::Rack::Utils::HTTP_STATUS_CODES[status].present?
|
44
|
-
|
45
|
-
raise Errors[500], 'Unknown response status code.'
|
46
|
-
end
|
47
|
-
|
48
|
-
# Validates a URL.
|
49
|
-
#
|
50
|
-
# @param url [String] The URL to validate.
|
51
|
-
# @return [NilClass] Returns *nil* if *url* is valid.
|
52
|
-
# @raise [Errors::InternalServerError] If the URL is invalid.
|
53
|
-
def validate_url!(url)
|
54
|
-
return if valid_url?(url)
|
55
|
-
|
56
|
-
raise Errors[500], "`#{url}' is not a valid URL."
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SharkOnLambda
|
4
|
-
module ApiGateway
|
5
|
-
module Errors
|
6
|
-
class Base < ::StandardError
|
7
|
-
attr_accessor :id, :code, :meta, :pointer, :parameter
|
8
|
-
attr_writer :detail
|
9
|
-
|
10
|
-
def self.status(status_code)
|
11
|
-
define_method :status do
|
12
|
-
status_code
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def detail
|
17
|
-
return @detail if @detail.present?
|
18
|
-
return nil if message == self.class.name
|
19
|
-
|
20
|
-
message
|
21
|
-
end
|
22
|
-
|
23
|
-
def title
|
24
|
-
::Rack::Utils::HTTP_STATUS_CODES[status]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.[](status_code)
|
29
|
-
@errors[status_code]
|
30
|
-
end
|
31
|
-
|
32
|
-
@errors = ::Rack::Utils::HTTP_STATUS_CODES.map do |status_code, message|
|
33
|
-
next unless (400..599).cover?(status_code) && message.present?
|
34
|
-
|
35
|
-
error_class = Class.new(Base) do
|
36
|
-
status status_code
|
37
|
-
end
|
38
|
-
class_name_parts = message.to_s.split(/\s+/)
|
39
|
-
class_name_parts.map! { |word| word.gsub(/[^a-z]/i, '').capitalize }
|
40
|
-
class_name = class_name_parts.join('')
|
41
|
-
const_set(class_name, error_class)
|
42
|
-
|
43
|
-
[status_code, error_class]
|
44
|
-
end
|
45
|
-
@errors.compact!
|
46
|
-
@errors = @errors.to_h
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SharkOnLambda
|
4
|
-
module ApiGateway
|
5
|
-
class Headers
|
6
|
-
def initialize
|
7
|
-
@headers = {}
|
8
|
-
end
|
9
|
-
|
10
|
-
def [](key)
|
11
|
-
@headers[normalized_key(key)]
|
12
|
-
end
|
13
|
-
|
14
|
-
def []=(key, value)
|
15
|
-
@headers[normalized_key(key)] = value.to_s
|
16
|
-
end
|
17
|
-
|
18
|
-
def delete(key)
|
19
|
-
@headers.delete(normalized_key(key))
|
20
|
-
end
|
21
|
-
|
22
|
-
def key?(key)
|
23
|
-
@headers.key?(normalized_key(key))
|
24
|
-
end
|
25
|
-
|
26
|
-
def to_h
|
27
|
-
@headers.dup
|
28
|
-
end
|
29
|
-
|
30
|
-
protected
|
31
|
-
|
32
|
-
def normalized_key(key)
|
33
|
-
key.to_s.downcase
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|