phaedra 0.4.0 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8a4e661423271591485445de16dbbbd5921bfd3f677e4c9cccfd08a3634b79b
4
- data.tar.gz: 513392234c9c02188d0fc20de6b83e0642133c0abdf246f4af9a7c06d72264dd
3
+ metadata.gz: 65ebfc3c9c8023c4a680704a085d9b4b62505fce1df1a82ca6d57bd9785c5ec2
4
+ data.tar.gz: d3384f2fa5d94ba594427970aad49cabe47b1d59d6f2a3289ba608c413e8d3db
5
5
  SHA512:
6
- metadata.gz: 8e6421d7c5bab7f3acc94e5858c1b7695df4ce71d2613c5f4d87821d9fcd96f23286c01bf49ea715343f51a23f534d91923498b0bd99265f7fb31474de42ffac
7
- data.tar.gz: d90e7402c1e8ea1d6c9afdd4fb530f4ad3fbbe289d59bff67d7dcf55b3783ec65778c5f41b625d1f4046acb3fc7d64f78160aec43f14d0738f8457bdc47b52eb
6
+ metadata.gz: c40e0c8017d3bb172a144b365ecaf62bc1d9b602c575740fefff8e0876ab54d853d1c5434aa2da8b8f02cda11d8f43084b5354d86464195374ee76799fd2e9c5
7
+ data.tar.gz: 763f60081477658fd4cfad3461cc8f9148c3c1c3e4d7f20d4571e1cf4d136c24c55a6aecfbc2c39c4ec3471bfadf7cca101be51dc7f3bcceb72c5e4eb21a2cdd
data/README.md CHANGED
@@ -1,9 +1,15 @@
1
1
  # Phaedra: Serverless Ruby Functions
2
2
 
3
- Phaedra is a web microframework for writing serverless Ruby functions. They are isolated pieces of logic which respond to HTTP requests (GET, POST, etc.) and typically get mounted at a particular URL path. They can be tested locally and deployed to a supported serverless hosting platform or to any [Rack-compatible web server](https://github.com/rack/rack).
3
+ Phaedra is a web microframework for writing serverless Ruby functions. They are isolated pieces of logic which respond to HTTP requests (GET, POST, etc.) and typically get mounted at a particular URL path. They can be tested locally and deployed to a supported serverless hosting platform, using a container via Docker & Docker Compose, or to any [Rack-compatible web server](https://github.com/rack/rack).
4
+
5
+ Phaedra is well-suited for building an API layer which you attach to a static site (aka [the Jamstack](https://www.bridgetownrb.com/docs/jamstack)) to provide dynamic functionality accessible any time after the static site loads in the browser.
4
6
 
5
7
  Serverless compatibility is presently focused on [Vercel](https://vercel.com) and [OpenFaaS](https://openfaas.com), but there are likely additional platforms we'll be adding support for in the future.
6
8
 
9
+ For swift deployment via Docker, we recommend [Fly.io](https://fly.io).
10
+
11
+ (P.S. Wondering how you can deploy a static site on [Netlify](https://www.netlify.com) and still use a Ruby API? Scroll down for a suggested approach!)
12
+
7
13
  ## Installation
8
14
 
9
15
  Add this line to your application's Gemfile:
@@ -24,18 +30,26 @@ Or install it yourself as:
24
30
  $ gem install phaedra
25
31
  ```
26
32
 
33
+ ## Examples
34
+
35
+ [Here's an example](https://github.com/whitefusionhq/phaedra/tree/master/example) of what the structure of a typical Phaedra app looks like. It includes `config.ru` for booting it up as a Rack app using Puma, as well as a `Dockerfile` and `docker-compose.yml` so you can run the app containerized in virtually any development or production hosting environment.
36
+
37
+ [Here's a demo](https://phaedra-demo.whitefusion.design/api/env) of one of the functions. [And another one.](https://phaedra-demo.whitefusion.design/api/params?search=Waiting%20for%20Guffman)
38
+
27
39
  ## Usage
28
40
 
29
41
  Functions are single Ruby files which respond to a URL path (aka `/api/path/to/function`). The path is determined by the location of the file on the filesystem relative to the functions root (aka `api`). So, given a path of `./api/folder/run-me.rb`, the URL path would be `/api/folder/run-me`.
30
42
 
31
43
  Functions are written as subclasses of `Phaedra::Base` using the name `PhaedraFunction`. The `params` argument is a Hash containing the parsed contents of the incoming query string, form data, or body JSON. The response object returned by your function is typically a Hash which will be transformed into JSON output automatically, but it can also be plain text.
32
44
 
45
+ Code to be run once upon function initialization and shared between multiple functions should be placed in the `phaedra/initializers.rb` file (see more on that below).
46
+
33
47
  Some platforms such as Vercel require the function class name to be `Handler`, so you can put that at the bottom of your file for full compatibility.
34
48
 
35
49
  Here's a basic example:
36
50
 
37
51
  ```ruby
38
- require "phaedra"
52
+ require_relative "../phaedra/initializers"
39
53
 
40
54
  class PhaedraFunction < Phaedra::Base
41
55
  def get(params)
@@ -60,17 +74,23 @@ Functions can define `action` callbacks:
60
74
  ```ruby
61
75
  class PhaedraFunction < Phaedra::Base
62
76
  before_action :do_stuff_before
63
- after_action :do_stuff_after
77
+ after_action do
78
+ # process response object further...
79
+ end
64
80
  around_action :do_it_all_around
65
81
 
66
82
  def do_stuff_before
67
- # code
83
+ # process request object before action handler...
68
84
  end
69
85
 
70
- # do_stuff_after, etc.
86
+ def do_it_all_around
87
+ # run code before
88
+ yield
89
+ # run code after
90
+ end
71
91
 
72
92
  def get(params)
73
- # this will be run within the callback chain
93
+ # this will be run within the entire callback chain
74
94
  end
75
95
  end
76
96
  ```
@@ -79,34 +99,51 @@ You can modify the `request` object in a `before_action` callback to perform set
79
99
 
80
100
  ### Shared Code You Only Want to Run Once
81
101
 
82
- You can use `require_relative` to load and execute shared Ruby code from another folder, say `lib`. This is particularly useful when setting up a database connection or performing expensive operations you only want to do once, rather than for every request.
102
+ Phaedra provides a default location to place shared modules and code that should be run once upon first deployment of your functions. This is particularly useful when setting up a database connection or performing expensive operations you only want to do once, rather than for every request.
103
+
104
+ Here's an example of how that works:
83
105
 
84
106
  ```ruby
85
107
  # api/run-it-once.rb
86
108
 
87
- require "phaedra"
88
- require_relative "../lib/shared_code"
109
+ require_relative "../phaedra/initializers"
89
110
 
90
111
  class PhaedraFunction < Phaedra::Base
91
112
  def get(params)
92
- "Run it once! #{SharedCode.run_once} / #{Time.now}"
113
+ "Run it once! #{Phaedra::Shared.run_once} / #{Time.now}"
93
114
  end
94
115
  end
95
116
  ```
96
117
 
97
118
  ```ruby
98
- # lib/shared_code.rb
119
+ # phaedra/initializers.rb
120
+
121
+ module Phaedra
122
+ module Shared
123
+ Initializers.register self do
124
+ run_once
125
+ end
99
126
 
100
- module SharedCode
101
- def self.run_once
102
- @one_time ||= Time.now
127
+ def self.run_once
128
+ @only_once ||= Time.now
129
+ end
103
130
  end
104
131
  end
105
132
  ```
106
133
 
107
- Now each time you invoke the function at `/api/run-it-once`, the first timestamp will never change until the next redeployment.
134
+ Now each time you invoke the function at `/api/run-it-once`, the timestamp will never change until the next redeployment.
135
+
136
+ **NOTE:** When running in a Rack-based configuration (see below), Ruby's `load` method is invoked for every request to any Phaedra function. This means Ruby has to parse and compile the code in your function each time. For small functions this happens extremely quickly, but if you find yourself writing a large function and seeing some performance slowdowns, consider extracting most of the function code to additional Ruby files and using the `require_relative` technique as mentioned above. The Ruby code in those required files will only be compiled once and all classes/modules/etc. will be saved in memory until the next redeployment.
137
+
138
+ ## Environment
139
+
140
+ You can set the environment of your Phaedra app using the `PHAEDRA_ENV` environment variable. That is then available via the `Phaedra.environment` method. By default, the value is `:development`.
141
+
142
+ ```ruby
143
+ # ENV["PHAEDRA_ENV"] == "production"
108
144
 
109
- **NOTE:** When running in a Rack-based configuration (see below), Ruby's `load` method is invoked for every request to any Phaedra function. This means Ruby has to parse and compile the code in your function each time. For small functions this happens extremely quickly, but if you find yourself writing a large function and seeing some performance slowdowns, consider extracting most of the function code to additional Ruby files and use the `require_relative` technique as mentioned above. The Ruby code in those required files will only be compiled once and all classes/modules/etc. will be saved in memory until the next redeployment.
145
+ Phaedra.environment == :production # true
146
+ ```
110
147
 
111
148
  ## Deployment
112
149
 
@@ -118,7 +155,13 @@ All you have to do is create a static site repo ([Bridgetown](https://www.bridge
118
155
 
119
156
  We recommend using OpenFaaS' dockerfile template so you can define your own `Dockerfile` to book Rack + Phaedra using the Puma web server. This also allows you to customize the Docker image configuration to install and configure other tools as necessary.
120
157
 
121
- First, make sure you've pulled down the template:
158
+ First make sure you've added Puma to your Gemfile:
159
+
160
+ ```
161
+ gem "puma"
162
+ ```
163
+
164
+ Then make sure you've pulled down the OpenFaaS template:
122
165
 
123
166
  ```sh
124
167
  faas-cli template store pull dockerfile
@@ -174,7 +217,7 @@ Next add the `config.ru` file to boot Rack:
174
217
  ```ruby
175
218
  # testphaedra/config.ru
176
219
 
177
- require "phaedra"
220
+ require "phaedra/rack_app"
178
221
 
179
222
  run Phaedra::RackApp.new
180
223
  ```
@@ -210,7 +253,7 @@ In case you're wondering: yes, with Phaedra you can write multiple Ruby function
210
253
  Booting Phaedra up as Rack app is very simple. All you need to do is add a `config.ru` file alongside your `api` folder:
211
254
 
212
255
  ```ruby
213
- require "phaedra"
256
+ require "phaedra/rack_app"
214
257
 
215
258
  run Phaedra::RackApp.new
216
259
  ```
@@ -246,6 +289,45 @@ server {
246
289
 
247
290
  Change the `server_name`, `root`, and `passenger_ruby` paths to your particular setup and you'll be good to go. (If you run into any errors, double-check there's a `config.ru` in the parent folder of your site destination folder.)
248
291
 
292
+ ### Docker
293
+
294
+ [In the example app provided](https://github.com/whitefusionhq/phaedra/tree/master/example), there is a `config.ru` file for booting it up as a Rack app using Puma. The `Dockerfile` and `docker-compose.yml` files allow you to easily build and deploy the app at port 8080 (but that can easily be changed). Using the Docker Compose commands:
295
+
296
+ ```sh
297
+ # Build (if necessary) and deploy:
298
+ docker-compose up
299
+
300
+ # Get information on the running container:
301
+ docker-compose ps
302
+
303
+ # Inspect the output logs:
304
+ docker-compose logs
305
+
306
+ # Exit the running container:
307
+ docker-compose down
308
+
309
+ # If you make changes to the code and need to rebuild:
310
+ docker-compose up --build
311
+ ```
312
+
313
+ #### Fly.io
314
+
315
+ Deploying your Phaedra app's Docker container via [Fly.io](https://fly.io) couldn't be easier. Simply create a new app and deploy using Fly.io's command line utility:
316
+
317
+ ```sh
318
+ # Create the new app using your Fly.io account:
319
+ flyctl apps create
320
+
321
+ # Deploy using the Dockerfile:
322
+ flyctl deploy
323
+
324
+ # Print out the URL and other info on your new app:
325
+ flyctl info
326
+
327
+ # Change the Phaedra app environment:
328
+ flyctl secrets set PHAEDRA_ENV=production
329
+ ```
330
+
249
331
  ### WEBrick
250
332
 
251
333
  Integrating Phaedra into a WEBrick server is pretty straightforward. Given a `server` object, it can be accomplished thusly:
@@ -280,7 +362,21 @@ load File.join(Dir.pwd, "api", "func.rb")
280
362
  @server.mount '/path', Handler
281
363
  ```
282
364
 
283
- This method precludes any automatic routing by Phaedra, so it's discouraged unless you are using WEBrick within a larger setup that utilizes its own routing method. (Interestingly enough, that's how Vercel works under the hood.)
365
+ This method precludes any automatic routing by Phaedra, so it's discouraged unless you are using WEBrick within a larger setup that utilizes its own routing method. (Interestingly enough, [that's how Vercel works under the hood](https://github.com/vercel/vercel/blob/master/packages/now-ruby/now_init.rb).)
366
+
367
+ ## Connecting a Static Site on Netlify to a Phaedra API
368
+
369
+ [Netlify](https://www.netlify.com) is a popular hosting solution for Jamstack (static) sites, but its serverless functions feature doesn't support Ruby. However, using proxy rewrites, you can deploy the static site part of your repository to Netlify and set the `/api` endpoint to route requests to your Phaedra app on the fly (hosted elsewhere).
370
+
371
+ For example, if your Phaedra app is hosted on Fly.io (see above), you'll want Netlify's CDN to proxy all requests to `/api/*` to that app's URL. We can accomplish that by adding a `_redirects` file to the static site's source folder (for Bridgetown sites, that's `src`):
372
+
373
+ ```
374
+ /api/* https://super-awesome-phaedra-api.fly.dev/api/:splat 200
375
+ ```
376
+
377
+ Once that deploys, you can go to your Netlify site URL, append `/api/whatever`, and under-the-hood that will connect to `https://super-awesome-phaedra-api.fly.dev/api/whatever` in a completely transparent manner.
378
+
379
+ If you want to change the proxy URL for different contexts (staging vs. production, etc.), you can follow Netlify's "[Separate _redirects files for separate contexts or branches](https://community.netlify.com/t/support-guide-making-redirects-work-for-you-troubleshooting-and-debugging/13433)" instructions here.
284
380
 
285
381
  ----
286
382
 
@@ -0,0 +1,46 @@
1
+ FROM ruby:2.6-alpine3.11 as builder
2
+
3
+ RUN apk add --no-cache --virtual \\
4
+ #
5
+ # required
6
+ bash tzdata build-base libffi-dev \\
7
+ #
8
+ # nice to haves
9
+ curl git
10
+
11
+ FROM builder as phaedra-app
12
+
13
+ # This is to fix an issue on Linux with permissions issues
14
+ ARG USER_ID=${USER_ID:-1000}
15
+ ARG GROUP_ID=${GROUP_ID:-1000}
16
+ ARG DOCKER_USER=${DOCKER_USER:-user}
17
+ ARG APP_DIR=${APP_DIR:-/home/user/phaedra-app}
18
+
19
+ # Change with --build-arg PHAEDRA_ENV=production
20
+ ARG PHAEDRA_ENV=development
21
+ ENV PHAEDRA_ENV=$PHAEDRA_ENV
22
+
23
+ # Create a non-root user
24
+ RUN addgroup -g $GROUP_ID -S $GROUP_ID
25
+ RUN adduser --disabled-password -G $GROUP_ID --uid $USER_ID -S $DOCKER_USER
26
+
27
+ # Create and then own the directory to fix permissions issues
28
+ RUN mkdir -p $APP_DIR
29
+ RUN chown -R $USER_ID:$GROUP_ID $APP_DIR
30
+
31
+ # Define the user running the container
32
+ USER $USER_ID:$GROUP_ID
33
+
34
+ # . now == $APP_DIR
35
+ WORKDIR $APP_DIR
36
+
37
+ # COPY is run as a root user, not as the USER defined above, so we must chown it
38
+ COPY --chown=$USER_ID:$GROUP_ID Gemfile* ./
39
+ RUN gem install bundler
40
+ RUN bundle install
41
+
42
+ COPY --chown=$USER_ID:$GROUP_ID . .
43
+
44
+ EXPOSE 8080
45
+
46
+ CMD ["bundle", "exec", "rackup", "-p", "8080", "-o", "0.0.0.0"]
@@ -1,4 +1,4 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "phaedra", path: ".."
3
+ gem "phaedra"
4
4
  gem "puma"
@@ -0,0 +1,19 @@
1
+ # Example Phaedra App
2
+
3
+ This will spin up a Phaedra demo API running on port 8080 (which can be changed).
4
+
5
+ ## Local Exec
6
+
7
+ Requires Ruby 2.6 or greater.
8
+
9
+ ```sh
10
+ bundle install
11
+
12
+ bundle exec rackup -p 8080
13
+ ```
14
+
15
+ ## Docker Compose
16
+
17
+ ```sh
18
+ docker-compose up
19
+ ```
@@ -0,0 +1,15 @@
1
+ require_relative "../phaedra/initializers"
2
+
3
+ class PhaedraFunction < Phaedra::Base
4
+ def get(params)
5
+ response["Content-Type"] = "text/html; charset=utf-8"
6
+ <<~HTML
7
+ <p>Hello friend! 😃</p>
8
+ <p>Startup Time: #{Phaedra::Shared.the_time}</p>
9
+ <p>Environment: #{Phaedra.environment}</p>
10
+ <p>Current Time: #{Time.new}</p>
11
+ HTML
12
+ end
13
+ end
14
+
15
+ Handler = PhaedraFunction
@@ -1,10 +1,10 @@
1
- require "phaedra"
1
+ require_relative "../phaedra/initializers"
2
2
 
3
3
  class PhaedraFunction < Phaedra::Base
4
4
  before_action :earlier_stuff
5
5
 
6
6
  def get(params)
7
- "The Current Time is: #{Time.new} and Search Param is #{params[:search]}."
7
+ "The ?search= param is #{params[:search] || "-missing-"}"
8
8
  end
9
9
 
10
10
  def post(params)
@@ -14,10 +14,10 @@ class PhaedraFunction < Phaedra::Base
14
14
  private
15
15
 
16
16
  def earlier_stuff
17
- request.query["search"] += " SEARCH!" if request.query["search"]
17
+ request.query["search"] += " (nice!)" if request.query["search"]
18
18
 
19
19
  if request.body
20
- request.body.sub!("Works", "Lurks")
20
+ request.body.sub!("Works", "Totally Works")
21
21
  end
22
22
  end
23
23
  end
@@ -1,3 +1,3 @@
1
- require "phaedra"
1
+ require "phaedra/rack_app"
2
2
 
3
3
  run Phaedra::RackApp.new
@@ -0,0 +1,8 @@
1
+ version: '3'
2
+ services:
3
+ web:
4
+ build: .
5
+ ports:
6
+ - "8080:8080"
7
+ environment:
8
+ - PHAEDRA_ENV
@@ -0,0 +1,14 @@
1
+ require "phaedra"
2
+ require "securerandom"
3
+
4
+ module Phaedra
5
+ module Shared
6
+ Initializers.register self do
7
+ the_time SecureRandom.hex(10)
8
+ end
9
+
10
+ def self.the_time(init = nil)
11
+ @the_time ||= "#{Time.now} (random seed: #{init})"
12
+ end
13
+ end
14
+ end
@@ -1,7 +1,5 @@
1
1
  require "phaedra/version"
2
-
3
2
  require "webrick"
4
- require "rack"
5
-
3
+ require "phaedra/initializers_module"
4
+ require "phaedra/startup_initializers"
6
5
  require "phaedra/base"
7
- require "phaedra/rack_app"
@@ -7,6 +7,10 @@ module Phaedra
7
7
  class Base
8
8
  include CallbacksActionable
9
9
 
10
+ before_action do
11
+ Initializers.run
12
+ end
13
+
10
14
  # Used by WEBrick
11
15
  def self.get_instance(server, *options)
12
16
  self.new(server, *options)
@@ -112,7 +116,7 @@ module Phaedra
112
116
 
113
117
  def set_initial_status
114
118
  @res.status = 200
115
- @res["Content-Type"] = "application/json"
119
+ @res["Content-Type"] = "application/json; charset=utf-8"
116
120
  end
117
121
 
118
122
  def call_method_action(params)
@@ -123,7 +127,7 @@ module Phaedra
123
127
  def complete_response
124
128
  if @res.body.is_a?(String) && !@res["Content-Type"].start_with?("text/")
125
129
  @res["Content-Type"] = "text/plain; charset=utf-8"
126
- elsif @res["Content-Type"] == "application/json"
130
+ elsif @res["Content-Type"].start_with? "application/json"
127
131
  @res.body = @res.body.to_json
128
132
  end
129
133
  end
@@ -11,14 +11,14 @@ module Phaedra
11
11
  end
12
12
 
13
13
  module ClassMethods
14
- def before_action(*args)
15
- set_callback :action, :before, *args
14
+ def before_action(*args, &block)
15
+ set_callback :action, :before, *args, &block
16
16
  end
17
- def after_action(*args)
18
- set_callback :action, :after, *args
17
+ def after_action(*args, &block)
18
+ set_callback :action, :after, *args, &block
19
19
  end
20
- def around_action(*args)
21
- set_callback :action, :around, *args
20
+ def around_action(*args, &block)
21
+ set_callback :action, :around, *args, &block
22
22
  end
23
23
  end
24
24
  end
@@ -0,0 +1,69 @@
1
+ module Phaedra
2
+ module Initializers
3
+ Registration = Struct.new(
4
+ :origin,
5
+ :priority,
6
+ :block,
7
+ keyword_init: true
8
+ ) do
9
+ def to_s
10
+ "#{owner}:#{priority} for #{block}"
11
+ end
12
+ end
13
+
14
+ DEFAULT_PRIORITY = 20
15
+
16
+ PRIORITY_MAP = {
17
+ low: 10,
18
+ normal: 20,
19
+ high: 30,
20
+ }.freeze
21
+
22
+ # initial empty hooks
23
+ @registry = []
24
+
25
+ NotAvailable = Class.new(RuntimeError)
26
+ Uncallable = Class.new(RuntimeError)
27
+
28
+ # Ensure the priority is a Fixnum
29
+ def self.priority_value(priority)
30
+ return priority if priority.is_a?(Integer)
31
+
32
+ PRIORITY_MAP[priority] || DEFAULT_PRIORITY
33
+ end
34
+
35
+ def self.register(origin, priority: DEFAULT_PRIORITY, &block)
36
+ raise Uncallable, "Initializers must respond to :call" unless block.respond_to? :call
37
+
38
+ @registry << Registration.new(
39
+ origin: origin,
40
+ priority: priority_value(priority),
41
+ block: block
42
+ )
43
+
44
+ block
45
+ end
46
+
47
+ def self.remove(origin)
48
+ @registry.delete_if { |item| item.origin == origin }
49
+ end
50
+
51
+ def self.run(force: false)
52
+ if !@initializers_ran || force
53
+ prioritized_initializers.each do |initializer|
54
+ initializer.block.call
55
+ end
56
+ end
57
+
58
+ @initializers_ran = true
59
+ end
60
+
61
+ def self.prioritized_initializers
62
+ # sort initializers according to priority and load order
63
+ grouped_initializers = @registry.group_by(&:priority)
64
+ grouped_initializers.keys.sort.reverse.map do |priority|
65
+ grouped_initializers[priority]
66
+ end.flatten
67
+ end
68
+ end
69
+ end
@@ -1,3 +1,6 @@
1
+ require "rack"
2
+ require "phaedra"
3
+
1
4
  module Phaedra
2
5
  class Request < Rack::Request
3
6
  def query
@@ -5,11 +8,18 @@ module Phaedra
5
8
  end
6
9
 
7
10
  def header
8
- @env.dup.transform_keys do |key|
11
+ @transformed_headers ||= @env.dup.transform_keys do |key|
9
12
  key.respond_to?(:downcase) ? key.downcase : key
13
+ end.tap do |headers|
14
+ # TODO: normalize a few common headers
15
+ headers["authorization"] = headers["http_authorization"]
10
16
  end
11
17
  end
12
18
 
19
+ def [](key)
20
+ header[key]
21
+ end
22
+
13
23
  def body
14
24
  @request_body ||= "" + get_header(Rack::RACK_INPUT).read
15
25
  end
@@ -0,0 +1,2 @@
1
+ require "phaedra/rack_middleware/not_found"
2
+ require "phaedra/rack_middleware/static"
@@ -6,7 +6,7 @@ module Phaedra
6
6
  class Static
7
7
  def initialize(app, options)
8
8
  @app = app
9
- @try = [".html", "index.html", "/index.html"] #, *options[:try]]
9
+ @try = ["", ".html", "index.html", "/index.html", *options[:try]]
10
10
  @static = Rack::Static.new(
11
11
  lambda { |_| [404, {}, []] },
12
12
  options)
@@ -0,0 +1,9 @@
1
+ module Phaedra
2
+ Initializers.register self, priority: :high do
3
+ environment
4
+ end
5
+
6
+ def self.environment
7
+ @environment ||= ENV.fetch("PHAEDRA_ENV", :development).to_sym
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module Phaedra
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phaedra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared White
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-11 00:00:00.000000000 Z
11
+ date: 2020-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -80,17 +80,23 @@ files:
80
80
  - LICENSE.txt
81
81
  - README.md
82
82
  - Rakefile
83
+ - example/Dockerfile
83
84
  - example/Gemfile
84
- - example/api/simple.rb
85
- - example/api/the-time.rb
85
+ - example/README.md
86
+ - example/api/env.rb
87
+ - example/api/params.rb
86
88
  - example/config.ru
89
+ - example/docker-compose.yml
90
+ - example/phaedra/initializers.rb
87
91
  - lib/phaedra.rb
88
92
  - lib/phaedra/base.rb
89
93
  - lib/phaedra/concerns/callbacks_actionable.rb
90
- - lib/phaedra/middleware.rb
91
- - lib/phaedra/middleware/not_found.rb
92
- - lib/phaedra/middleware/static.rb
94
+ - lib/phaedra/initializers_module.rb
93
95
  - lib/phaedra/rack_app.rb
96
+ - lib/phaedra/rack_middleware.rb
97
+ - lib/phaedra/rack_middleware/not_found.rb
98
+ - lib/phaedra/rack_middleware/static.rb
99
+ - lib/phaedra/startup_initializers.rb
94
100
  - lib/phaedra/version.rb
95
101
  - phaedra.gemspec
96
102
  homepage: https://github.com/whitefusionhq/phaedra
@@ -112,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
118
  - !ruby/object:Gem::Version
113
119
  version: '0'
114
120
  requirements: []
115
- rubygems_version: 3.0.6
121
+ rubygems_version: 3.0.8
116
122
  signing_key:
117
123
  specification_version: 4
118
124
  summary: Write serverless Ruby functions via a REST-like microframework compatible
@@ -1,10 +0,0 @@
1
- require "phaedra"
2
-
3
- class PhaedraFunction < Phaedra::Base
4
- def get(params)
5
- response["Content-Type"] = "text/html; charset=utf-8"
6
- "<p>This is Interesting. 😁</p>"
7
- end
8
- end
9
-
10
- Handler = PhaedraFunction
@@ -1,2 +0,0 @@
1
- require "phaedra/middleware/not_found"
2
- require "phaedra/middleware/static"