trialday 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d77199f6b23c06e721942c3cb229a7793d2f0669
4
- data.tar.gz: 071aff33072a0c73b7a26e316ada99e418fd69a8
3
+ metadata.gz: d1ba05c9f8eab2a210334a8231bc4d4f5b4973cc
4
+ data.tar.gz: 24ac3c8da03bb1182152e842e089edc5a6814c62
5
5
  SHA512:
6
- metadata.gz: 8be9e4a744caa8fc82d00cd60efae91b13d3af3d8e6be56ed80a7f342031b09adfd084f1f8726d2ffa64986232e005535c04fed471bb1596e5945df4801364aa
7
- data.tar.gz: 2bc88122cf0ab0d914881fafaa60282917b0f0a2fb93acc154ea92715245d495731284186adc5442002e2031111dd70b432ab7abcbe251fce9594c86ae2def18
6
+ metadata.gz: 90d9d58fb6dc484bbd24c17a38f74023d1bcc786cba237d48d2cd4177dd7875ec20eec20cd45b4ee4b07c52a4da89f9e1e1bb551b5156b62bed4560f92335403
7
+ data.tar.gz: 137dccd43ea5c1a1831c11b26f2f21a98d5d03e30b7ef365f6b8c3744829aa9fc1b811309d772ddf4490895337376d5d3443066b8ef980e3cd9ced3ce8cb0586
data/lib/trialday.rb CHANGED
@@ -1,17 +1,35 @@
1
- app_files = File.expand_path('../app/**/*.rb', __FILE__)
2
- Dir.glob(app_files).each { |file| require(file) }
1
+ #--
2
+ # Trialday
3
+ #
4
+ # Trialday is a small web framework for writing simple JSON APIs.
5
+ # It's Rack based (https://rack.github.io/).
6
+ #
7
+ # The architecture is composed of 3 main layers, that are represented
8
+ # below with base, mains and router.
9
+ #
10
+ # Trial day is a reverse engineering of Sinatra
11
+ # [https://github.com/sinatra/sinatra/tree/master/lib/sinatra]
12
+ #++
13
+ require 'rack'
14
+ require 'trialday/base'
15
+ require 'trialday/router'
16
+ require 'trialday/main'
3
17
 
4
- class Trialday
5
- def call(env)
6
- request = Rack::Request.new(env)
7
- serve_request(request)
8
- end
9
18
 
10
- def serve_request(request)
11
- Router.new(request).route!
12
- end
13
- end
19
+ # = Trialday Delegator
20
+ #
21
+ # In order to public expose the get and set methods, we use metaprogramming
22
+ # defining both of them in a dynamic way. The defined methods are then
23
+ # extended in this main file to it they can be accessed from outside.
24
+ # The idea comes from Sinatra base: lib/sinatra/base.rb#L1918
25
+ #
26
+ # PS: include would include the module in Object
27
+ # while extend only extends the `main` object
28
+ extend Trialday::Delegator
14
29
 
15
- def get x, &block
16
- Rack::Handler::WEBrick.run Trialday.new
30
+ # = Rack Builder
31
+ #
32
+ # Implements a small DSL to iteratively construct Rack applications.
33
+ class Rack::Builder
34
+ include Trialday::Delegator
17
35
  end
@@ -0,0 +1,42 @@
1
+ # = Trialday Base
2
+ #
3
+ # The Base class contains the integrations between the Application class
4
+ # and the router. It uses class methods to, when called, invoke the
5
+ # Router.route. This will add the new route to the list of available routes.
6
+ # [see Sinatra: lib/sinatra/base.rb#L1599]
7
+ #
8
+ # = Trialday Delegator
9
+ #
10
+ # The Delegator dynamic creates the integrations between the public
11
+ # api and the Trialday::Application class. It generates get/post methods
12
+ # on the fly and by metaprogramming defines what should happen whe the API
13
+ # is called. The Application is then registered to accept the parameters,
14
+ # calling passing the routes path and body block to the scope.
15
+ # [see Sinatra: lib/sinatra/base.rb#L1908]
16
+ module Trialday
17
+
18
+ class Base
19
+ class << self
20
+ # Defining a `GET` handler
21
+ def get(path, &block)
22
+ Trialday::Router.route(path, 'GET', &block)
23
+ end
24
+ # Defining a `POST` handler
25
+ def post(path, &block)
26
+ Trialday::Router.route(path, 'POST', &block)
27
+ end
28
+ end
29
+ end
30
+
31
+ module Delegator #:nodoc:
32
+ def self.delegate(*methods)
33
+ methods.each do |method_name|
34
+ define_method(method_name) do |*args, &block|
35
+ Trialday::Application.send(method_name, *args, &block)
36
+ end
37
+ end
38
+ end
39
+
40
+ delegate :get, :post
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ # = Trialday Application
2
+ #
3
+ # Rack Applications needs an object which will have a 'call' method.
4
+ # This call method can be simple and just return a HTTP response.
5
+ # In our scenario this class will get the reference from Rack::Request
6
+ # and call the 'serve_request' method.
7
+ #
8
+ # The serve_request method returns the Trialday::Router.
9
+ # the ida is to have an main object to orchestrate the possible
10
+ # calls to the framework API.
11
+ #
12
+ # To start up the Rack server we use ruby's at_exist method.
13
+ # This will ensure that the Router object will be completely ready
14
+ # for Rack to server, in this case, using WEBrick.
15
+ # [see Sinatra: /lib/sinatra/main.rb#L26]
16
+ module Trialday
17
+
18
+ class Application < Base
19
+ def call(env)
20
+ request = Rack::Request.new(env)
21
+ serve_request(request)
22
+ end
23
+
24
+ def serve_request(request)
25
+ Router.new(request).route!
26
+ end
27
+ end
28
+
29
+ at_exit { Rack::Handler::WEBrick.run Trialday::Application.new }
30
+ end
@@ -0,0 +1,79 @@
1
+ # = Trialday Router
2
+ #
3
+ # The Router for Trialday framework.
4
+ # The Router is responsible to keep a collections of paths
5
+ # and knows where and what to return. It verifies if the request is a get
6
+ # or post, and check to see if the API was pre-defined with an response for
7
+ # the desired call.
8
+ #
9
+ # This class uses ideas from Sinatra, and could be extensively improved.
10
+ # For now, it uses a routes list that could be tweaked.
11
+ # The framework also includes a 'not_foud' route in case the Router wasn't
12
+ # configured to respond to a specific call.
13
+ # [see Sinatra: ib/sinatra/base.rb#L1602]
14
+ require 'json'
15
+
16
+ module Trialday
17
+ class Router
18
+ @@routes = []
19
+
20
+ def initialize(request)
21
+ @request = request
22
+ end
23
+
24
+ def route!
25
+ routes_list.each do |r|
26
+ if action == r['path']
27
+ verb = @request.get? ? 'GET' : 'POST'
28
+ if verb == 'GET'
29
+ return [200, { "Content-Type" => "application/json" }, [r['body'].call.to_json]]
30
+ elsif verb == 'POST'
31
+ return [200, { "Content-Type" => "application/json" }, [@request.body.read]]
32
+ end
33
+ end
34
+ end
35
+
36
+ not_found
37
+ end
38
+
39
+ def action
40
+ '/'+ route_info[:resource]
41
+ end
42
+
43
+ def routes_list
44
+ @@routes
45
+ end
46
+
47
+ class << self
48
+ def route(path, verb, &block)
49
+ @@routes << {"path"=>path, "body"=>block, "verb"=>"GET"}
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def not_found(msg = "Route not found.")
56
+ [404, { "Content-Type" => "text/plain" }, [msg]]
57
+ end
58
+
59
+ def route_info
60
+ @route_info ||= begin
61
+ resource = path_fragments[0]
62
+ { resource: resource }
63
+ end
64
+ end
65
+
66
+ def find_id_and_action(fragment)
67
+ @request.get? ? :index : :create
68
+ end
69
+
70
+ def add_route_info_to_request_params!
71
+ @request.params.merge!(route_info)
72
+ end
73
+
74
+ def path_fragments
75
+ @fragments ||= @request.path.split("/").reject { |s| s.empty? }
76
+ end
77
+
78
+ end
79
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trialday
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anderson Leite
@@ -17,6 +17,9 @@ extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
19
  - lib/trialday.rb
20
+ - lib/trialday/base.rb
21
+ - lib/trialday/main.rb
22
+ - lib/trialday/router.rb
20
23
  homepage: http://rubygems.org/gems/trialday
21
24
  licenses:
22
25
  - MIT