jets 5.0.0.beta1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -1
- data/README.md +20 -36
- data/lib/jets/builders/code_builder.rb +1 -1
- data/lib/jets/builders/templates/handlers/one_lambda_for_all_controllers.rb +1 -1
- data/lib/jets/cfn/resource/api_gateway/rest_api/routes/change/base.rb +2 -1
- data/lib/jets/cfn/resource/api_gateway/rest_api/routes/change.rb +11 -5
- data/lib/jets/commands/releases/releases_command.rb +1 -1
- data/lib/jets/core.rb +7 -1
- data/lib/jets/dotenv/ssm.rb +3 -0
- data/lib/jets/generators/overrides/app/helpers.rb +0 -4
- data/lib/jets/generators/overrides/app/templates/.env +10 -0
- data/lib/jets/router/matcher.rb +7 -3
- data/lib/jets/version.rb +1 -1
- metadata +6 -5
- /data/lib/jets/generators/overrides/app/templates/{.gitignore → .gitignore.tt} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54e94ceb6d67976943a212a5ccceb71bb3e7bd6c6928775c0e7b824be127e42d
|
4
|
+
data.tar.gz: cab6dba2a8108c047daec4706e15d226e0e7f4eb46e9b6f2617465ea186b451e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c050d7738b47e826403bc383baa0b2db251246b3d3dc359135e8e1039f8404448021477b38fbfab57f2be1cd09f7ffe8aa925cff70e313a96e61735f46f4fee2
|
7
|
+
data.tar.gz: 152c89e1b3e9d124f63687181f48c13ef09e3140062665a6b11baf9a99e830869cd7c8df46a2e1e8e59c58bc08bbb76d6430d235fd296ed176bcf0628890531a
|
data/CHANGELOG.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/).
|
5
5
|
|
6
|
-
## [5.0.0] -
|
6
|
+
## [5.0.0] - 2023-12-05
|
7
7
|
Single Lambda Function for Controllers
|
8
8
|
* For controllers, a single Lambda function is deployed going forward.
|
9
9
|
* APIGW serves as proxy endpoint for requests to the single Lambda function. Techniquely, there are 2 APIGW endpoints.
|
@@ -55,10 +55,13 @@ Breaking changes:
|
|
55
55
|
* Jets.config.prewarm.concurrency option removed.
|
56
56
|
* dynomite decoupling and integration improvements
|
57
57
|
|
58
|
+
## [4.0.10] - 2023-12-04
|
59
|
+
- [#678](https://github.com/boltops-tools/jets/pull/678) handle option method or http_method from route state
|
58
60
|
|
59
61
|
## [4.0.9] - 2023-12-03
|
60
62
|
- [#674](https://github.com/boltops-tools/jets/pull/674) Fix broken --mode jobs new project generation
|
61
63
|
- [#675](https://github.com/boltops-tools/jets/pull/675) Add resource tags to CloudFormation stack
|
64
|
+
|
62
65
|
## [4.0.8] - 2023-12-03
|
63
66
|
- [#677](https://github.com/boltops-tools/jets/pull/677) pin dynomite 1.2.7
|
64
67
|
|
data/README.md
CHANGED
@@ -16,12 +16,13 @@ Please **watch/star** this repo to help grow and support the project.
|
|
16
16
|
|
17
17
|
## What is Ruby on Jets?
|
18
18
|
|
19
|
-
Jets is a Ruby Serverless Framework.
|
19
|
+
Jets is a Ruby Serverless Framework. Jets allows you to create serverless applications with a beautiful language: Ruby. It includes everything required to build and deploy an application to AWS Lambda.
|
20
20
|
|
21
|
-
|
21
|
+
Understanding AWS Lambda and API Gateway is key to understanding Jets conceptually. Jets map your code to Lambda functions and other AWS Resources like API Gateway and Event Rules.
|
22
22
|
|
23
|
-
* **AWS Lambda** is
|
23
|
+
* **AWS Lambda** is functions as a service. It allows you to upload and run functions without worrying about the underlying infrastructure.
|
24
24
|
* **API Gateway** is the routing layer for Lambda. It is used to route REST URL endpoints to Lambda functions.
|
25
|
+
* **EventBridge Rules** are events as a service. You can automatically run Lambda functions triggered from AWS services. You decide what events to catch and how to react to them.
|
25
26
|
|
26
27
|
The official documentation is at [Ruby on Jets](http://rubyonjets.com).
|
27
28
|
|
@@ -42,14 +43,14 @@ end
|
|
42
43
|
|
43
44
|
Here's the function in the Lambda console:
|
44
45
|
|
45
|
-
![Code Example in AWS Lambda console](https://
|
46
|
+
![Code Example in AWS Lambda console](https://img.boltops.com/tools/jets/readme/simple-lambda-function.png)
|
46
47
|
|
47
48
|
|
48
|
-
Though simple functions are supported by Jets, they do not add much value as other ways to write Ruby code with Jets. Classes like [Controllers](http://rubyonjets.com/docs/controllers/) and [Jobs](http://rubyonjets.com/docs/jobs/) add many conveniences and are more powerful to use. We’ll cover them next.
|
49
|
+
Though simple functions are supported by Jets, they do not add as much value as other ways to write Ruby code with Jets. Classes like [Controllers](http://rubyonjets.com/docs/controllers/) and [Jobs](http://rubyonjets.com/docs/jobs/) add many conveniences and are more powerful to use. We’ll cover them next.
|
49
50
|
|
50
51
|
### Jets Controllers
|
51
52
|
|
52
|
-
A Jets controller handles a web request and renders a response.
|
53
|
+
A Jets controller handles a web request and renders a response. Here's an example:
|
53
54
|
|
54
55
|
app/controllers/posts_controller.rb:
|
55
56
|
|
@@ -69,11 +70,9 @@ class PostsController < ApplicationController
|
|
69
70
|
end
|
70
71
|
```
|
71
72
|
|
72
|
-
Helper methods like `params` provide the parameters from the API Gateway event. The `render` method
|
73
|
+
Helper methods like `params` provide the parameters from the API Gateway event. The `render` method returns a Lambda Proxy structure that API Gateway understands.
|
73
74
|
|
74
|
-
Jets creates Lambda functions
|
75
|
-
|
76
|
-
![Lambda Functions for each public method in AWS Console](https://raw.githubusercontent.com/tongueroo/jets/master/docs/img/docs/demo-lambda-functions-controller.png)
|
75
|
+
Jets creates single Lambda functions to handle your Jets Controller requests. The Lambda Function handler is a shim that routes to your controller action.
|
77
76
|
|
78
77
|
### Jets Routing
|
79
78
|
|
@@ -83,23 +82,14 @@ config/routes.rb:
|
|
83
82
|
|
84
83
|
```ruby
|
85
84
|
Jets.application.routes.draw do
|
86
|
-
|
87
|
-
get "posts/new", to: "posts#new"
|
88
|
-
get "posts/:id", to: "posts#show"
|
89
|
-
post "posts", to: "posts#create"
|
90
|
-
get "posts/:id/edit", to: "posts#edit"
|
91
|
-
put "posts", to: "posts#update"
|
92
|
-
delete "posts", to: "posts#delete"
|
93
|
-
|
94
|
-
resources :comments # expands to the RESTful routes above
|
95
|
-
|
85
|
+
resources :posts
|
96
86
|
any "posts/hot", to: "posts#hot" # GET, POST, PUT, etc request all work
|
97
87
|
end
|
98
88
|
```
|
99
89
|
|
100
90
|
The `routes.rb` gets translated to API Gateway resources:
|
101
91
|
|
102
|
-
![API Gateway Resources generated from routes in AWS console](https://
|
92
|
+
![API Gateway Resources generated from routes in AWS console](https://img.boltops.com/tools/jets/readme/apigw.png)
|
103
93
|
|
104
94
|
Test your API Gateway endpoints with curl or postman. Note, replace the URL endpoint with the one that is created:
|
105
95
|
|
@@ -111,7 +101,7 @@ Test your API Gateway endpoints with curl or postman. Note, replace the URL endp
|
|
111
101
|
|
112
102
|
### Jets Jobs
|
113
103
|
|
114
|
-
A Jets job handles asynchronous background jobs
|
104
|
+
A Jets job handles asynchronous background jobs outside the web request/response cycle. Here's an example:
|
115
105
|
|
116
106
|
app/jobs/hard_job.rb:
|
117
107
|
|
@@ -129,9 +119,13 @@ class HardJob < ApplicationJob
|
|
129
119
|
end
|
130
120
|
```
|
131
121
|
|
132
|
-
|
122
|
+
![Jets Jobs in AWS Lambda Console](https://img.boltops.com/tools/jets/readme/jets-jobs.png)
|
123
|
+
|
124
|
+
`HardJob#dig` runs every 10 hours, and `HardJob#lift` runs every 12 hours. The `rate` and `cron` methods created CloudWatch Event Rules. Example:
|
125
|
+
|
126
|
+
![CloudWatch Event Rules in AWS Console](https://img.boltops.com/tools/jets/readme/jets-jobs-event-rules.png)
|
133
127
|
|
134
|
-
|
128
|
+
This simple example uses Scheduled Events. There are many more possibilities, see the [Events Docs](https://docs.rubyonjets.com/docs/events/).
|
135
129
|
|
136
130
|
### Jets Deployment
|
137
131
|
|
@@ -141,29 +135,19 @@ You can test your application with a local server that mimics API Gateway: [Jets
|
|
141
135
|
|
142
136
|
After deployment, you can test the Lambda functions with the AWS Lambda console or the CLI.
|
143
137
|
|
144
|
-
### AWS Lambda Console
|
145
|
-
|
146
|
-
![Lambda Console](https://s3.amazonaws.com/boltops-demo/images/screenshots/lambda-console-posts-controller-index.png)
|
147
|
-
|
148
138
|
### Live Demos
|
149
139
|
|
150
140
|
Here are some demos of Jets applications:
|
151
141
|
|
152
142
|
* [Quintessential CRUD Jets app](https://demo.rubyonjets.com/)
|
153
143
|
* [API Demo](https://api.demo.rubyonjets.com/)
|
154
|
-
* [Jets Afterburner: Easy Rails Support](https://afterburner.demo.rubyonjets.com/)
|
155
|
-
* [Mega Mode: Jets and Rails Combined](https://mega.demo.rubyonjets.com/)
|
156
144
|
* [Image Upload with CarrierWave](https://upload.demo.rubyonjets.com/)
|
157
145
|
|
158
|
-
Please feel free to add your
|
159
|
-
|
160
|
-
### Rails Support
|
161
|
-
|
162
|
-
[Jets Afterburner Mode](http://rubyonjets.com/docs/rails-support/) provides Rails support with little effort. This allows you to run a Rails application on AWS Lambda. Also here's a Tutorial Blog Post: [Jets Afterburner: Rails Support](https://blog.boltops.com/2018/12/21/jets-afterburner-serverless-rails-on-aws-lambda-in-5-minutes).
|
146
|
+
Please feel free to add your examples to the [rubyonjets/examples](https://github.com/rubyonjets/examples) repo.
|
163
147
|
|
164
148
|
### More Info
|
165
149
|
|
166
|
-
For more documentation, check out the official docs: [Ruby on Jets](http://rubyonjets.com/).
|
150
|
+
For more documentation, check out the official docs: [Ruby on Jets](http://rubyonjets.com/). Here's a list of useful links:
|
167
151
|
|
168
152
|
* [Quick Start](http://rubyonjets.com/quick-start/)
|
169
153
|
* [Local Jets Server](http://rubyonjets.com/docs/local-server/)
|
@@ -233,7 +233,7 @@ module Jets::Builders
|
|
233
233
|
# Checking this way because when using jets standalone for Afterburner mode we don't want to run into
|
234
234
|
# bundler gem collisions. TODO: figure out the a better way to handle the collisions.
|
235
235
|
lines = IO.readlines("#{Jets.root}/Gemfile")
|
236
|
-
lines.detect { |l| l =~ /#{name}/ }
|
236
|
+
lines.detect { |l| l =~ /#{name}/ && l !~ /\s.*#/ }
|
237
237
|
end
|
238
238
|
|
239
239
|
# Cleans out non-cached files like code-*.zip in Jets.build_root
|
@@ -8,7 +8,7 @@ def lambda_handler(event:, context:)
|
|
8
8
|
return
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
<% if @vars.process_type == "controller" -%>
|
12
12
|
route = Jets::Router.find_route_by_event(event)
|
13
13
|
controller = route.controller_name
|
14
14
|
action = route.action_name
|
@@ -14,8 +14,9 @@ class Jets::Cfn::Resource::ApiGateway::RestApi::Routes::Change
|
|
14
14
|
return [] if data.nil?
|
15
15
|
|
16
16
|
data.map do |item|
|
17
|
+
http_method = item.dig('options','method') || item.dig('options','http_method')
|
17
18
|
Jets::Router::Route.new(
|
18
|
-
http_method:
|
19
|
+
http_method: http_method,
|
19
20
|
path: item['path'],
|
20
21
|
to: item['to'],
|
21
22
|
engine: item['engine'],
|
@@ -5,13 +5,19 @@ class Jets::Cfn::Resource::ApiGateway::RestApi::Routes
|
|
5
5
|
|
6
6
|
def changed?
|
7
7
|
return false unless parent_stack_exists?
|
8
|
-
return
|
8
|
+
return true if reset?
|
9
|
+
|
9
10
|
# Note: Variable.changed? will likely always true in one_apigw_method_for_all_routes mode
|
10
|
-
# since parent variables are allowed to vary.
|
11
|
+
# since parent variables are allowed to vary in Jets v5.
|
12
|
+
if Jets.config.cfn.build.routes == "one_apigw_method_for_all_routes"
|
13
|
+
MediaTypes.changed? || To.changed?
|
14
|
+
else
|
15
|
+
MediaTypes.changed? || To.changed? || Variable.changed? || Page.changed?
|
16
|
+
end
|
17
|
+
end
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
ENV['JETS_RESET'] || ENV['JETS_API_REPLACE'] || ENV['JETS_REPLACE_API']
|
19
|
+
def reset?
|
20
|
+
ENV['JETS_RESET'] || ENV['JETS_API_REPLACE'] || ENV['JETS_REPLACE_API']
|
15
21
|
end
|
16
22
|
|
17
23
|
def parent_stack_exists?
|
data/lib/jets/core.rb
CHANGED
@@ -88,7 +88,13 @@ module Jets::Core
|
|
88
88
|
def parsed_project_name
|
89
89
|
lines = IO.readlines("#{Jets.root}/config/application.rb")
|
90
90
|
project_name_line = lines.find { |l| l =~ /config\.project_name.*=/ && l !~ /^\s+#/ }
|
91
|
-
|
91
|
+
if project_name_line
|
92
|
+
parsed = project_name_line.gsub(/.*=/,'').strip
|
93
|
+
# The +? makes it non-greedy
|
94
|
+
# See: https://ruby-doc.org/core-2.5.1/Regexp.html#class-Regexp-label-Repetition
|
95
|
+
md = parsed.match(/['"](.+?)['"]/)
|
96
|
+
md ? md[1] : raise("Unable to parse project name from config/application.rb: #{project_name_line}")
|
97
|
+
end
|
92
98
|
end
|
93
99
|
memoize :parsed_project_name
|
94
100
|
|
data/lib/jets/dotenv/ssm.rb
CHANGED
@@ -45,6 +45,9 @@ class Jets::Dotenv
|
|
45
45
|
rescue Aws::SSM::Errors::ParameterNotFound
|
46
46
|
@missing << [key, value, name]
|
47
47
|
''
|
48
|
+
rescue Aws::SSM::Errors::ValidationException
|
49
|
+
puts "ERROR: Invalid SSM parameter name: #{name.inspect}".color(:red)
|
50
|
+
raise
|
48
51
|
end
|
49
52
|
|
50
53
|
def ssm_name(key, value)
|
@@ -56,7 +56,6 @@ module Jets::Generators::Overrides::App
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def copy_project
|
59
|
-
# directory ".", project_folder, copy_options
|
60
59
|
directory ".", ".", copy_options
|
61
60
|
end
|
62
61
|
|
@@ -69,9 +68,6 @@ module Jets::Generators::Overrides::App
|
|
69
68
|
excludes.uniq!
|
70
69
|
|
71
70
|
unless @database
|
72
|
-
# Do not even generate the config/database.yml because
|
73
|
-
# Jets webpacker:install bombs and tries to load the db since it sees a
|
74
|
-
# config/database.yml but there's no database pg gem configured.
|
75
71
|
excludes += %w[
|
76
72
|
database.yml
|
77
73
|
db
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Variables in here are available and shared across all environments: development, production, etc
|
2
|
+
# Docs: https://docs.rubyonjets.com/docs/env-files/
|
3
|
+
|
4
|
+
# Examples:
|
5
|
+
# DATABASE_URL="mysql2://user:pass@host.com/db_name?pool=5" # raw value as-is
|
6
|
+
# SSM can be use to reference a parameter store value
|
7
|
+
# DATABASE_URL=SSM # conventionally references /PROJECT_NAME/JETS_ENV/DATABASE_URL
|
8
|
+
# DATABASE_URL=SSM # /demo/development/DATABASE_URL
|
9
|
+
# DATABASE_URL=SSM:database-url # /demo/development/database-url
|
10
|
+
# DATABASE_URL=SSM:/path/to/database-url # /path/to/database-url
|
data/lib/jets/router/matcher.rb
CHANGED
@@ -32,7 +32,7 @@ module Jets::Router
|
|
32
32
|
# Checking the request_method_from_hidden_method_field so that handler can find the right route
|
33
33
|
# super early in the process. Otherwise lambda routes to the wrong controller action.
|
34
34
|
@request_method = request_method || @request.request_method_from_hidden_method_field || @request.request_method.to_s.upcase
|
35
|
-
@request_path = @request.path
|
35
|
+
@request_path = strip_format(@request.path)
|
36
36
|
route = find_route
|
37
37
|
match_constraints(route) if route
|
38
38
|
end
|
@@ -43,7 +43,7 @@ module Jets::Router
|
|
43
43
|
def find_by_env(env)
|
44
44
|
@env = env
|
45
45
|
@request_method = env["REQUEST_METHOD"] || "GET"
|
46
|
-
@request_path = env["PATH_INFO"]
|
46
|
+
@request_path = strip_format(env["PATH_INFO"])
|
47
47
|
find_route
|
48
48
|
end
|
49
49
|
|
@@ -87,12 +87,16 @@ module Jets::Router
|
|
87
87
|
end
|
88
88
|
memoize :mount
|
89
89
|
|
90
|
+
def strip_format(path)
|
91
|
+
path.sub(/\..+$/, '') # Remove format from the end of the path
|
92
|
+
end
|
93
|
+
|
90
94
|
def match?(route)
|
91
95
|
# Immediately stop checking when the request http_method: GET, POST, ANY, etc
|
92
96
|
# doesnt match.
|
93
97
|
return false if request_method != route.http_method && route.http_method != "ANY"
|
94
98
|
|
95
|
-
route_path = route.path
|
99
|
+
route_path = strip_format(route.path)
|
96
100
|
route_path = "#{mount.at}#{route_path}" if mount
|
97
101
|
|
98
102
|
if request_path == route_path
|
data/lib/jets/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.0
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tung Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-12-
|
11
|
+
date: 2023-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionmailer
|
@@ -962,7 +962,8 @@ files:
|
|
962
962
|
- lib/jets/generators/overrides/app/USAGE
|
963
963
|
- lib/jets/generators/overrides/app/app_generator.rb
|
964
964
|
- lib/jets/generators/overrides/app/helpers.rb
|
965
|
-
- lib/jets/generators/overrides/app/templates/.
|
965
|
+
- lib/jets/generators/overrides/app/templates/.env
|
966
|
+
- lib/jets/generators/overrides/app/templates/.gitignore.tt
|
966
967
|
- lib/jets/generators/overrides/app/templates/.rspec
|
967
968
|
- lib/jets/generators/overrides/app/templates/Gemfile.tt
|
968
969
|
- lib/jets/generators/overrides/app/templates/README.md
|
@@ -1187,9 +1188,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
1187
1188
|
version: 2.7.0
|
1188
1189
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
1189
1190
|
requirements:
|
1190
|
-
- - "
|
1191
|
+
- - ">="
|
1191
1192
|
- !ruby/object:Gem::Version
|
1192
|
-
version:
|
1193
|
+
version: '0'
|
1193
1194
|
requirements: []
|
1194
1195
|
rubygems_version: 3.4.20
|
1195
1196
|
signing_key:
|
File without changes
|