rubapi 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a6890dbc0ab667734bdfe53a3fe18191ab9feaa0
4
+ data.tar.gz: 9ef2394c0cfd8ac737ffac797cb4ad2cce93d4d9
5
+ SHA512:
6
+ metadata.gz: 53bc2dc997a2110369af6bad7543dc11683a6976c9d50164e74d965c153c0faeba0088ecdf411c99df6b6f7175a6be493065a420e089fdd15f2cf01f7a3b2e40
7
+ data.tar.gz: 46554545f3146bc95ecadb7585fc90b3dbb491b35086830fa41e18720b9fd5cbb610106791a3104ad183a90a9df1843263e2d5f2bdb580e346b730a975a4c3b3
@@ -0,0 +1,50 @@
1
+ module Rubapi
2
+ class Controller
3
+ attr_accessor :request, :response, :params
4
+
5
+ def initialize(response)
6
+ self.response = response
7
+ end
8
+
9
+ def index
10
+ end
11
+
12
+ def show
13
+ end
14
+
15
+ def create
16
+ end
17
+
18
+ def update
19
+ end
20
+
21
+ def delete
22
+ end
23
+
24
+ def run(route)
25
+ if route.nil?
26
+ response.status = 404
27
+ response.send_response
28
+
29
+ return response
30
+ end
31
+
32
+ route[:controller] ||= self.class
33
+ controller = route[:controller].new(self.response)
34
+ controller.params = self.params
35
+
36
+ response.tap do |r|
37
+ r.status = 200
38
+
39
+ begin
40
+ r.content = JSON.generate(controller.send(route[:method]))
41
+ rescue
42
+ r.content = "{\"errors\":[\"can't generate a json object\"]}"
43
+ r.status = 417 #Execution failed
44
+ ensure
45
+ r.send_response
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,17 @@
1
+ module Rubapi
2
+ class Request
3
+ attr_accessor :params,
4
+ :errors,
5
+ :route
6
+
7
+ def initialize(route)
8
+ self.route = route
9
+ self.params = {}
10
+ self.errors = []
11
+ end
12
+
13
+ def parse_params(param_string)
14
+ self.params = self.params.merge(Rack::Utils.parse_nested_query(param_string))
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,114 @@
1
+ module Rubapi
2
+ class Router
3
+ class << self
4
+ attr_accessor :routes
5
+
6
+ def resource(resource)
7
+ self.routes ||= []
8
+ if @nested_resource
9
+ @current_resource[:nested] << rest_resource(resource)
10
+ else
11
+ self.routes << rest_resource(resource)
12
+ end
13
+ @current_resource = find_resource([resource])
14
+
15
+ @nested_resource = true
16
+ yield if block_given?
17
+ @nested_resource = false
18
+ end
19
+
20
+ def fetch(path, verb)
21
+ paths = path.split("/")
22
+ resources = paths.select{|pa| /([a-z]+)/.match pa }.map(&:to_sym)
23
+ resources = find_resource(resources)
24
+
25
+ return nil if resources.nil?
26
+
27
+ resources[:actions][verb].each do |re|
28
+ resource_path = re[:path].split("/")
29
+ if paths.count == resource_path.count
30
+ params = resource_path.select{|pa| /:([a-z_]+)/.match pa }
31
+
32
+ request = re.clone
33
+ request[:params] = extract_params(paths, params)
34
+ request[:controller] = resources[:controller]
35
+ return request
36
+ end
37
+ end
38
+
39
+ false
40
+ end
41
+
42
+ def extract_params(uri_params, params)
43
+ result = {}
44
+ if params.any?
45
+ for i in 1..(params.size)
46
+ key = params[i-1]
47
+ key[0]=''
48
+ result[key] = uri_params[i*2]
49
+ end
50
+ end
51
+
52
+ result
53
+ end
54
+
55
+
56
+ def find_resource(resources)
57
+ self.routes ||= []
58
+
59
+ resource = resources.shift
60
+
61
+ root = self.routes.select{|route| route[:name] == resource}.first
62
+ while(resources.any?)
63
+ resource = resources.shift
64
+ if root[:nested].any?
65
+ root = root[:nested].select {|route| route[:name] == resource}.first
66
+ end
67
+ end
68
+
69
+ root
70
+ end
71
+
72
+
73
+ def blank_resource(resource)
74
+ {
75
+ name: resource,
76
+ actions: {
77
+ get: [],
78
+ post: [],
79
+ put: [],
80
+ delete:[]
81
+ },
82
+ nested: [],
83
+ controller: nil
84
+ }
85
+ end
86
+
87
+ def rest_resource(resource)
88
+ path = "/#{resource}"
89
+ if @nested_resource
90
+ path = "/#{@current_resource[:name]}/:#{@current_resource[:name]}_id/#{resource}"
91
+ end
92
+ blank_resource(resource).tap do |rest|
93
+ rest[:actions][:get] << { method: :index , path: "#{path}" }
94
+ rest[:actions][:get] << { method: :show , path: "#{path}/:#{resource}_id" }
95
+ rest[:actions][:post] << { method: :create , path: "#{path}" }
96
+ rest[:actions][:put] << { method: :update , path: "#{path}/:#{resource}_id" }
97
+ rest[:actions][:delete] << { method: :delete , path: "#{path}/:#{resource}_id" }
98
+ end
99
+ end
100
+
101
+ def without(*actions)
102
+ actions.first.each do |verb, actions|
103
+ @current_resource[:actions]
104
+ .select{|key,actions| verb == key }[verb]
105
+ .delete_if{|action| actions.include?(action[:method]) }
106
+ end
107
+ end
108
+
109
+ def controller(klass)
110
+ @current_resource[:controller] = klass
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,27 @@
1
+ module Rubapi
2
+ class Server < EM::Connection
3
+ include EM::HttpServer
4
+
5
+ class << self
6
+ attr_accessor :rest_routes
7
+
8
+ def route_with(routes)
9
+ self.rest_routes = routes
10
+ end
11
+ end
12
+
13
+
14
+ def build_params
15
+ Request.new.tap do |r|
16
+ r.parse(@http_query_string)
17
+ r.parse(@http_post_content)
18
+ end
19
+ end
20
+
21
+ def process_http_request
22
+
23
+ controller = Controller.new(EM::DelegatedHttpResponse.new(self))
24
+ controller.run Server.rest_routes.fetch(@http_request_uri, @http_request_method.downcase.to_sym)
25
+ end
26
+ end
27
+ end
data/lib/rubapi.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "rack"
2
+ require "eventmachine"
3
+ require "evma_httpserver"
4
+ require "json"
5
+ require_relative "rubapi/router"
6
+ require_relative "rubapi/controller"
7
+ require_relative "rubapi/server"
8
+
9
+
10
+ module Rubapi
11
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubapi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Ricardo K. Sasaki
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eventmachine
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: '0'
25
+ prerelease: false
26
+ type: :runtime
27
+ - !ruby/object:Gem::Dependency
28
+ name: eventmachine_httpserver
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ version_requirements: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ prerelease: false
40
+ type: :runtime
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ version_requirements: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ prerelease: false
54
+ type: :runtime
55
+ - !ruby/object:Gem::Dependency
56
+ name: json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ prerelease: false
68
+ type: :runtime
69
+ description: A RESTful router built on top of EventMachine prepared to serve RethinkDB's
70
+ data
71
+ email: ricardo@followit.ninja
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - lib/rubapi.rb
77
+ - lib/rubapi/controller.rb
78
+ - lib/rubapi/request.rb
79
+ - lib/rubapi/router.rb
80
+ - lib/rubapi/server.rb
81
+ homepage: https://rubygems.org/gems/rubapi
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.5.1
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: ruby RESTful API created to serve RethinkDB data
105
+ test_files: []