shark-on-lambda 1.0.0.rc4 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
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 +19 -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 +14 -54
  9. data/lib/shark_on_lambda/api_gateway_handler.rb +3 -55
  10. data/lib/shark_on_lambda/application.rb +75 -5
  11. data/lib/shark_on_lambda/base_controller.rb +29 -9
  12. data/lib/shark_on_lambda/cacheable.rb +21 -0
  13. data/lib/shark_on_lambda/configuration.rb +1 -65
  14. data/lib/shark_on_lambda/inferrers/serializer_inferrer.rb +10 -7
  15. data/lib/shark_on_lambda/jsonapi_renderer.rb +16 -10
  16. data/lib/shark_on_lambda/middleware/base.rb +2 -4
  17. data/lib/shark_on_lambda/middleware/honeybadger.rb +14 -9
  18. data/lib/shark_on_lambda/middleware/jsonapi_rescuer.rb +21 -1
  19. data/lib/shark_on_lambda/middleware/lambda_logger.rb +8 -16
  20. data/lib/shark_on_lambda/rake_tasks.rb +16 -0
  21. data/lib/shark_on_lambda/request.rb +0 -3
  22. data/lib/shark_on_lambda/rspec/env_builder.rb +71 -34
  23. data/lib/shark_on_lambda/rspec/helpers.rb +5 -87
  24. data/lib/shark_on_lambda/rspec/request_helpers.rb +63 -0
  25. data/lib/shark_on_lambda/rspec/{jsonapi_helpers.rb → response_helpers.rb} +4 -10
  26. data/lib/shark_on_lambda/version.rb +1 -1
  27. data/shark-on-lambda.gemspec +7 -5
  28. metadata +32 -37
  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 -37
  35. data/lib/shark_on_lambda/query.rb +0 -67
  36. data/lib/shark_on_lambda/rack_adapters/api_gateway.rb +0 -128
  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: f6a831332c510a5977edd5ca1db24a68a9cf7cc323433fb807f5b65a707df0e7
4
- data.tar.gz: 9beabc2ae1d3d81d9a6b10d80b69668629d902726c535dc3aec403db4ac38c36
3
+ metadata.gz: 63f4b1de2142973e7e2214530bfcebe66427c76eac109a5e4107210b3842c10b
4
+ data.tar.gz: 9a4dbec8d0c428033548a37929306fa3e63cfb8c86bb32d7d6559413476291ef
5
5
  SHA512:
6
- metadata.gz: b607fdff10e8ff558fb85e3d92bc9697e783aaf2f856822fe84591101f974d89af3cd9a11c41640409c5f0590fb9ef0bf9b0c86e68029112388cd0a110283a08
7
- data.tar.gz: 4ea5be6f0d30ce7b6f4a05632a9b9c1c96ce18673cb52be4907cdf726fb56982052a06f16874eeb772947ad387b2472d3079e585087146aee7865035ef6a42f7
6
+ metadata.gz: 99896684ede88efb1f6e1269fa01de0ba4b9dc91d8b8008f6143a18129aa893c7e178264de975d2b6e2874d2c2c077bcaf3003792fdda7bd5fe54f12d339df6e
7
+ data.tar.gz: 61fb3d19fbcfa4fdad7173cc83c85235176e52938665f4997b80199669ef04a6008f8f2035d49607eca10650154495b7b0fee2e3ad655cd026ee1fd60c2d2f52
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,24 @@
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 `SharkOnLambda::Cacheable`.
13
+ - Added `SharkOnLambda.cache` and `SharkOnLambda.global_cache`.
14
+ - Added support for routing.
15
+ - Use `rack-on-lambda` as an adapter for events from the (REST API flavoured) API Gateway.
16
+
17
+ #### 1.0.1
18
+
19
+ - [Fix] `Jsonapi::Renderer#render` should always return a hash.
20
+
21
+ #### 1.0.0
4
22
 
5
23
  - [Break] HTTP redirection now uses the status code `302`.
6
24
  - [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,75 +38,32 @@ module SharkOnLambda
35
38
  class << self
36
39
  extend Forwardable
37
40
 
38
- attr_writer :logger
41
+ attr_writer :application, :cache, :env, :global_cache, :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)
53
+ def cache
54
+ @cache ||= ActiveSupport::Cache::NullStore.new
52
55
  end
53
56
 
54
- def initialize!
55
- enable_jsonapi!
56
-
57
- yield(config, secrets)
58
-
59
- Configuration.load(stage)
60
- Secrets.load(stage)
61
- run_initializers
62
-
63
- true
57
+ def env
58
+ @env || ENV['STAGE'].presence || 'development'
64
59
  end
65
60
 
66
- def load_configuration
67
- Configuration.load(stage)
68
- Secrets.load(stage)
69
-
70
- true
61
+ def global_cache
62
+ @global_cache ||= ActiveSupport::Cache::NullStore.new
71
63
  end
72
64
 
73
65
  def logger
74
- @logger ||= Logger.new(STDOUT)
75
- end
76
-
77
- def reset_configuration
78
- known_stage = config.stage
79
- known_root = config.root
80
-
81
- Configuration.reset
82
- Secrets.reset
83
-
84
- config.root = known_root
85
- config.stage = known_stage
86
-
87
- true
88
- end
89
-
90
- def secrets
91
- Secrets.instance
92
- end
93
-
94
- private
95
-
96
- def enable_jsonapi!
97
- ::Mime::Type.register('application/vnd.api+json', :jsonapi)
98
- ::ActionDispatch::Request.parameter_parsers[:jsonapi] =
99
- ::ActionDispatch::Request.parameter_parsers[:json].dup
100
- end
101
-
102
- def run_initializers
103
- initializers_path = root.join('config', 'initializers')
104
- Dir.glob(initializers_path.join('*.rb')).each do |path|
105
- load path
106
- end
66
+ @logger ||= Logger.new($stdout)
107
67
  end
108
68
  end
109
69
  end