shark-on-lambda 1.0.0.rc2 → 2.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -3
  3. data/.rubocop.yml +4 -0
  4. data/README.md +70 -17
  5. data/changelog.md +17 -1
  6. data/doc/upgrade-from-0.6.x-to-1.x.md +122 -0
  7. data/lib/shark-on-lambda.rb +9 -0
  8. data/lib/shark_on_lambda.rb +10 -50
  9. data/lib/shark_on_lambda/api_gateway_handler.rb +3 -55
  10. data/lib/shark_on_lambda/application.rb +73 -5
  11. data/lib/shark_on_lambda/base_controller.rb +29 -9
  12. data/lib/shark_on_lambda/configuration.rb +1 -65
  13. data/lib/shark_on_lambda/inferrers/serializer_inferrer.rb +10 -7
  14. data/lib/shark_on_lambda/jsonapi_renderer.rb +16 -10
  15. data/lib/shark_on_lambda/middleware/base.rb +2 -4
  16. data/lib/shark_on_lambda/middleware/honeybadger.rb +45 -0
  17. data/lib/shark_on_lambda/middleware/jsonapi_rescuer.rb +21 -1
  18. data/lib/shark_on_lambda/middleware/lambda_logger.rb +8 -16
  19. data/lib/shark_on_lambda/rake_tasks.rb +16 -0
  20. data/lib/shark_on_lambda/request.rb +0 -3
  21. data/lib/shark_on_lambda/rspec/env_builder.rb +73 -31
  22. data/lib/shark_on_lambda/rspec/helpers.rb +5 -74
  23. data/lib/shark_on_lambda/rspec/request_helpers.rb +63 -0
  24. data/lib/shark_on_lambda/rspec/{jsonapi_helpers.rb → response_helpers.rb} +4 -6
  25. data/lib/shark_on_lambda/version.rb +1 -1
  26. data/shark-on-lambda.gemspec +7 -5
  27. metadata +32 -38
  28. data/gems.locked +0 -142
  29. data/lib/shark_on_lambda/concerns/resettable_singleton.rb +0 -18
  30. data/lib/shark_on_lambda/concerns/yaml_config_loader.rb +0 -28
  31. data/lib/shark_on_lambda/dispatcher.rb +0 -26
  32. data/lib/shark_on_lambda/inferrers/name_inferrer.rb +0 -66
  33. data/lib/shark_on_lambda/jsonapi_controller.rb +0 -29
  34. data/lib/shark_on_lambda/middleware/rescuer.rb +0 -38
  35. data/lib/shark_on_lambda/query.rb +0 -67
  36. data/lib/shark_on_lambda/rack_adapters/api_gateway.rb +0 -127
  37. data/lib/shark_on_lambda/secrets.rb +0 -43
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 404addc89268452b9ffbc6bb94ad7133dcac67f9df3f419abf0b673a5de20493
4
- data.tar.gz: 328a87cf1a29c0e0322731ec83b94e4a0f029f87a8e37c1615062fc132da7b4d
3
+ metadata.gz: 642998e593034c083639724031920edfe7568de50d276cc3c58932c099d94a0e
4
+ data.tar.gz: 8101e725e3ef4f710422625726f87c7a324e986b9eb6184a988e0fdd3812bdda
5
5
  SHA512:
6
- metadata.gz: 7874706fa45ad80560518176e9a5ee6f6f61c0e139ec785f6ce90e8aeed04e023a8fa890c121ca93b53203d25589b0d6a8cefdc5eb82f590eb040010d4c13890
7
- data.tar.gz: 70fb9f45d5ad2c92d6643c1d20bf5aa70ff1883233814604870b2993501b761df588e577aa119d5b089c573fa86220183d10f4b076bf5587b5b3be9fc0e82e3a
6
+ metadata.gz: d23eac59ce2797aac609444509d571a54ffb22024f11070a54dd43d600ceeeb2b527e421c1c9463ac08cceb4fa2b9ad6a366e496cebb47c2873276e9abf4a9ec
7
+ data.tar.gz: 8932eeb3134b88fb0da09b35a3a70eb1b4d1bfb5b2a1f522b9f4bc23c07890b4c6c9cd061374aebf4eb80c09695ef69420da95cc7f608c415b81692724f41e56
data/.gitignore CHANGED
@@ -2,15 +2,14 @@
2
2
  /.yardoc
3
3
  /_yardoc/
4
4
  /coverage/
5
- /doc/
6
5
  /pkg/
7
6
  /spec/reports/
8
7
  /tmp/
9
8
 
9
+ gems.locked
10
+
10
11
  # rspec failure tracking
11
12
  .rspec_status
12
13
 
13
14
  # Add gems to `vendor/cache`
14
15
  vendor/cache/*
15
- !vendor/cache/bima*.gem
16
- !vendor/cache/shark*.gem
@@ -1,4 +1,5 @@
1
1
  AllCops:
2
+ NewCops: enable
2
3
  TargetRubyVersion: 2.5
3
4
 
4
5
  Metrics/BlockLength:
@@ -6,6 +7,9 @@ Metrics/BlockLength:
6
7
  - 'spec/**/*_spec.rb'
7
8
  - 'spec/factories/*.rb'
8
9
 
10
+ Layout/LineLength:
11
+ Max: 80
12
+
9
13
  Naming/FileName:
10
14
  Exclude:
11
15
  - lib/shark-on-lambda.rb
data/README.md CHANGED
@@ -25,12 +25,19 @@ maintaining a smaller memory footprint.
25
25
 
26
26
  Have a look at the [actual changelog](changelog.md).
27
27
 
28
+ ## Upgrading?
29
+
30
+ If you are upgrading from a previous version of `shark-on-lambda`, these
31
+ upgrade guides might be of some help to you.
32
+
33
+ * [Upgrading from `v0.6.x` to `v1.x`](doc/upgrade-from-0.6.x-to-1.x.md)
34
+
28
35
  ## Installation
29
36
 
30
37
  Add this line to your application's `gems.rb`:
31
38
 
32
39
  ```ruby
33
- gem 'shark_on_lambda'
40
+ gem 'shark-on-lambda'
34
41
  ```
35
42
 
36
43
  And then execute:
@@ -39,7 +46,7 @@ And then execute:
39
46
 
40
47
  Or install it yourself:
41
48
 
42
- $ gem install shark_on_lambda
49
+ $ gem install shark-on-lambda
43
50
 
44
51
  ## Handlers
45
52
 
@@ -48,11 +55,11 @@ are triggered by HTTP requests on the API Gateway. They also are responsible for
48
55
  responding with a well-formed response to the caller.
49
56
 
50
57
  ```ruby
51
- class MyHandler < SharkOnLambda::BaseHandler
58
+ class MyHandler < SharkOnLambda::ApiGatewayHandler
52
59
  end
53
60
  ```
54
61
 
55
- By inheriting from `SharkOnLambda::BaseHandler`, your own handler
62
+ By inheriting from `SharkOnLambda::ApiGatewayHandler`, your own handler
56
63
  class is indirectly tied to your controller class by convention: It assumes
57
64
  the controller name is `MyController` and it will dispatch events to that
58
65
  controller.
@@ -78,7 +85,7 @@ class MyController < SharkOnLambda::BaseController
78
85
  end
79
86
  end
80
87
 
81
- class MyHandler < SharkOnLambda::BaseHandler
88
+ class MyHandler < SharkOnLambda::ApiGatewayHandler
82
89
  end
83
90
  ```
84
91
 
@@ -89,16 +96,13 @@ handler class method is called.
89
96
 
90
97
  ## Controllers
91
98
 
92
- Controllers are similar to Rails controllers: In addition to having access to
93
- the AWS Lambda `event` and `context` objects, you also have access to `params`,
94
- `request`, and `response` objects that are derived from the `event` object.
99
+ Controllers are similar to Rails controllers: You have access to `params`,
100
+ `request`, and `response` objects that contain informatoni retrieved from the
101
+ AWS Lambda `event` object.
95
102
 
96
103
  ### "Basic" controllers
97
104
 
98
- You also have access to the `render` and `redirect_to` methods __that are not as
99
- powerful as the Rails equivalent by far__. There are none of the `render_*`
100
- functions you may know from Rails and `render` does not really support multiple
101
- renderers (yet).
105
+ You also have access to the `render` and `redirect_to`.
102
106
 
103
107
  ```ruby
104
108
  class MyController < SharkOnLambda::BaseController
@@ -113,17 +117,19 @@ class MyController < SharkOnLambda::BaseController
113
117
  def show
114
118
  # Does what you think it does.
115
119
  #
116
- # The default status code for `redirect_to` is 307.
117
- redirect_to 'https://github.com', status: 302
120
+ # The default status code for `redirect_to` is 302.
121
+ redirect_to 'https://github.com', status: 307
118
122
  end
119
123
  end
120
124
  ```
121
125
 
126
+ `before_action`, `around_action`, and `after_action` filters also are available,
127
+ as well as `rescue_from`.
128
+
122
129
  ### _JSON API_-compliant controllers
123
130
 
124
- If you inherit your controller from
125
- `SharkOnLambda::JsonapiController`, `render` and `redirect_to` will
126
- create _JSON API_-compliant responses.
131
+ If you inherit your controller from `SharkOnLambda::JsonapiController`,
132
+ `render` and `redirect_to` will create _JSON API_-compliant responses.
127
133
 
128
134
  You however __must__ have a serialiser for the objects you want to render.
129
135
  Otherwise, rendering will fail and you will receive an _Internal Server Error_
@@ -196,6 +202,53 @@ If `SharkOnLambda.config.stage` was set inside the block passed to
196
202
  the default set (the `default` node in the YAML files) of configuration and
197
203
  secrets, overwriting values where applicable.
198
204
 
205
+ ## Test helpers
206
+
207
+ By including `SharkOnLambda::RSpec::Helpers` in your RSpec test suite, you can
208
+ use `delete`, `get`, `patch`, `post`, and `put` methods, which will return
209
+ a `Rack::MockResponse` object. You can also access that response object in your
210
+ test examples by calling `response`, but only after you've called either of the
211
+ aforementioned methods. Otherwise, an exception will be raised.
212
+
213
+ You can include the test helpers like this in your `spec/spec_helper.rb`.
214
+
215
+ ```ruby
216
+ RSpec.configure do |config|
217
+ config.include SharkOnLambda::RSpec::Helpers
218
+ end
219
+ ```
220
+
221
+ ### _JSON API_ helpers
222
+
223
+ By including `SharkOnLambda::RSpec::JsonapiHelpers`, you gain all the goodies
224
+ from `SharkOnLambda::RSpec::Helpers` _and_ access to `jsonapi_data` and
225
+ `jsonapi_errors` methods, which contain the `data` and `errors` keys of the
226
+ parsed response body respectively. In addition to that, there is
227
+ `jsonapi_attributes`, which returns the `attributes` key from `jsonapi_data`.
228
+
229
+ ## _Rack_ compatibility
230
+
231
+ As `SharkOnLambda.application` is a _Rack_-compatible application, treating it
232
+ as such and using existing _Rack_ middleware is straightforward.
233
+
234
+ ### Using _Rack_ middleware
235
+
236
+ The middleware stack can be found at `SharkOnLambda.config.middleware`. Adding
237
+ middleware to your stack can be either done by calling `#use`:
238
+
239
+ ```ruby
240
+ SharkOnLambda.config.middleware.use Your::Middleware
241
+ ```
242
+
243
+ You can also just set up your middleware stack during your
244
+ `SharkOnLambda.initialize!` call:
245
+
246
+ ```ruby
247
+ SharkOnLambda.initialize! do |config, secrets|
248
+ config.middleware.use Your::Middleware
249
+ end
250
+ ```
251
+
199
252
  ## Development
200
253
 
201
254
  Clone this repository and change away. Then, once you are done, please submit
@@ -1,6 +1,22 @@
1
1
  ## Changelog
2
2
 
3
- #### Unreleaesed
3
+ #### Unreleased
4
+
5
+ #### 2.0.0
6
+ - [Deprecate] Requiring `shark-on-lambda` is marked as deprecated in favour of requiring `shark_on_lambda`.
7
+ - [Break] `SharkOnLambda::Dispatcher` was removed in favour of routing via `ActionDispatch::Routing`.
8
+ - [Break] `SharkOnLambda::BaseController` now renders _JSON API_-compliant responses.
9
+ - [Break] `SharkOnLambda::JsonapiController` was removed.
10
+ - [Break] Support for `path_parameters` in RSpec helpers was removed.
11
+ - [Break] Configuration files are not loaded automatically anymore.
12
+ - Added support for routing.
13
+ - Use `rack-on-lambda` as an adapter for events from the (REST API flavoured) API Gateway.
14
+
15
+ #### 1.0.1
16
+
17
+ - [Fix] `Jsonapi::Renderer#render` should always return a hash.
18
+
19
+ #### 1.0.0
4
20
 
5
21
  - [Break] HTTP redirection now uses the status code `302`.
6
22
  - [Break] Remove the `ApiGateway` namespace, move all items from that namespace up by one level.
@@ -0,0 +1,122 @@
1
+ # Upgrading from version `0.6.x` to version `1.x`
2
+
3
+ ## Mandatory changes
4
+
5
+ ### `SharkOnLambda::ApiGateway::*` => `SharkOnLambda::*`
6
+
7
+ The `ApiGateway` module was removed in favour of a shallower hierarchy, because
8
+ `shark-on-lambda` only really does lifting work in an HTTP request context.
9
+
10
+ ### `SharkOnLambda::ApiGateway::BaseHandler` => `SharkOnLambda::ApiGatewayHandler`
11
+
12
+ In an attempt to make the ties to the _API Gateway_ a bit more explicit, the
13
+ handler base class now is `SharkOnLambda::ApiGatewayHandler` instead of what
14
+ might be expected to be `SharkOnLambda::BaseHandler`.
15
+
16
+ ### Use `SharkOnLambda::RSpec::JsonapiHelpers` (or `SharkOnLambda::RSpec::Helpers`)
17
+
18
+ Until now, making a request to your application has involved building your own
19
+ _API Gateway_ event object and then passing it to your handler/controller.
20
+
21
+ If you have been passing the event object to your handlers solely, this change
22
+ is optional. If you however have been passing the event object to your
23
+ controllers, upgrading `shark-on-lambda` to `v1.x` makes changing the way your
24
+ tests run a necessity, because controller do not know about _API Gateway_ events
25
+ anymore and thus cannot handle them properly.
26
+
27
+ The recommended way to test controllers is to use
28
+ `SharkOnLambda::RSpec::JsonapiHelpers` (or `SharkOnLambda::RSpec::Helpers`) in
29
+ your RSpec tests and then use the methods `delete`, `get`, `patch`, `post`, or
30
+ `put` to test your controllers like this:
31
+
32
+ ```ruby
33
+ RSpec.describe MyController do
34
+ let(:service_token) { 'my-super-secret-service-token' }
35
+ let(:headers) do
36
+ {
37
+ 'authorization' => "Bearer #{service_token}"
38
+ }
39
+ end
40
+ let(:params) do
41
+ {
42
+ id: 1
43
+ }
44
+ end
45
+
46
+ subject { get :show, headers: headers, params: params }
47
+
48
+ it { expect(subject.status).to eq(200) }
49
+ end
50
+ ```
51
+
52
+ If you, for some reason, want to distinguish between `params` and
53
+ `path_parameters`, you can also pass in `path_parameters` using the
54
+ `path_parameters:` keyword argument like this:
55
+
56
+ ```ruby
57
+ get :show, headers: headers, params: params, path_parameters: path_parameters
58
+ ```
59
+
60
+ Using `SharkOnLambda::RSpec::JsonapiHelpers` or `SharkOnLambda::RSpec::Helpers`
61
+ also lets you access the `response` object in your test examples. This object
62
+ is an instance of `Rack::MockResponse`, which you might be familiar with from
63
+ e. g. controller testing in Rails.
64
+
65
+ You can use these helpers by e. g. setting them up in `spec/spec_helper.rb`:
66
+
67
+ ```ruby
68
+ RSpec.configure do |config|
69
+ config.include SharkOnLambda::RSpec::JsonapiHelpers
70
+ end
71
+ ```
72
+
73
+ ## Recommended changes
74
+
75
+ ### Move to a _Rack_-compatible implementation for CORS headers
76
+
77
+ Until now, the way to add CORS headers prior to sending the response to the
78
+ _API Gateway_ has been to "decorate" the `#call` method in your handler, e. g.
79
+ using a module like
80
+
81
+ ```ruby
82
+ module CORS
83
+ def call(action, event:, context:)
84
+ response = super
85
+ response[:headers].reverse_merge!(
86
+ 'access-control-allow-origin' => '*',
87
+ 'access-control-allow-credentials' => 'true'
88
+ )
89
+ response
90
+ end
91
+ end
92
+ ```
93
+
94
+ and then including it in your handler:
95
+
96
+ ```ruby
97
+ class MyHandler < SharkOnLambda::ApiGateway::BaseHandler
98
+ include CORS
99
+ end
100
+ ```
101
+
102
+ This _still_ works for the time being, but it is recommended to switch to an
103
+ approach based on using _Rack_ middleware, e. g. `rack-cors` or implementing
104
+ your own middleware.
105
+
106
+ ### Use `SharkOnLambda::Middleware::JsonapiRescuer` (or `SharkOnLambda::Middleware::Rescuer`)
107
+
108
+ Until now, `shark-on-lambda` has caught all uncaught exceptions before building
109
+ the response object for _API Gateway_, turning those exceptions into sensible
110
+ response objects.
111
+
112
+ This behaviour changes drastically with `v1.0.0`: Exceptions are not being
113
+ caught by the main application anymore. Therefore, it is recommended to add
114
+ `SharkOnLambda::Middleware::JsonapiRescuer`
115
+ (or `SharkOnLambda::Middleware::Rescuer`) to your middleware stack to restore
116
+ this kind of behaviour.
117
+
118
+ ```ruby
119
+ SharkOnLambda.initialize! do |config, secrets|
120
+ config.middleware.use SharkOnLambda::Middleware::JsonapiRescuer
121
+ end
122
+ ```
@@ -1,3 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support/core_ext/string'
4
+ require 'active_support/deprecation'
5
+
6
+ deprecation_message = <<-MESSAGE.squish
7
+ Requiring `shark-on-lambda` is deprecated and will be removed in version 3.0.
8
+ Please require `shark_on_lambda` instead.
9
+ MESSAGE
10
+ ActiveSupport::Deprecation.warn(deprecation_message, caller(2))
11
+
3
12
  require 'shark_on_lambda'
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'pry' if Gem.loaded_specs.key?('pry')
4
4
 
5
+ require 'erb'
5
6
  require 'forwardable'
6
7
  require 'ostruct'
7
8
  require 'pathname'
@@ -14,6 +15,7 @@ require 'active_support/all'
14
15
  require 'jsonapi/deserializable'
15
16
  require 'jsonapi/serializable'
16
17
  require 'rack/utils'
18
+ require 'rack-on-lambda'
17
19
  require 'yaml'
18
20
  require 'zeitwerk'
19
21
 
@@ -22,6 +24,7 @@ module SharkOnLambda; end
22
24
 
23
25
  Zeitwerk::Loader.for_gem.tap do |loader|
24
26
  loader.ignore(File.expand_path('shark-on-lambda.rb', __dir__))
27
+ loader.ignore(File.expand_path('shark_on_lambda/rake_tasks.rb', __dir__))
25
28
  loader.inflector.inflect(
26
29
  'rspec' => 'RSpec',
27
30
  'version' => 'VERSION'
@@ -35,67 +38,24 @@ module SharkOnLambda
35
38
  class << self
36
39
  extend Forwardable
37
40
 
38
- attr_writer :logger
41
+ attr_writer :application, :env, :logger
39
42
 
40
- def_instance_delegators :config, :root, :stage
43
+ def_instance_delegators :application, :initialize!, :root
41
44
 
42
45
  def application
43
46
  @application ||= Application.new
44
47
  end
45
48
 
46
- def config
47
- Configuration.instance
49
+ def configuration
50
+ application.config
48
51
  end
49
52
 
50
- def configure
51
- yield(config, secrets)
52
- end
53
-
54
- def initialize!
55
- yield(config, secrets)
56
-
57
- Configuration.load(stage)
58
- Secrets.load(stage)
59
- run_initializers
60
-
61
- true
62
- end
63
-
64
- def load_configuration
65
- Configuration.load(stage)
66
- Secrets.load(stage)
67
-
68
- true
53
+ def env
54
+ @env || ENV['STAGE'].presence || 'development'
69
55
  end
70
56
 
71
57
  def logger
72
- @logger ||= Logger.new(STDOUT)
73
- end
74
-
75
- def reset_configuration
76
- known_stage = config.stage
77
- known_root = config.root
78
-
79
- Configuration.reset
80
- Secrets.reset
81
-
82
- config.root = known_root
83
- config.stage = known_stage
84
-
85
- true
86
- end
87
-
88
- def secrets
89
- Secrets.instance
90
- end
91
-
92
- protected
93
-
94
- def run_initializers
95
- initializers_path = root.join('config', 'initializers')
96
- Dir.glob(initializers_path.join('*.rb')).each do |path|
97
- load path
98
- end
58
+ @logger ||= Logger.new($stdout)
99
59
  end
100
60
  end
101
61
  end