Class: GRApiManager::Server
- Inherits:
-
Object
- Object
- GRApiManager::Server
- Defined in:
- lib/gr_api_manager.rb
Instance Attribute Summary collapse
-
#app_class ⇒ Object
readonly
Returns the value of attribute app_class.
Instance Method Summary collapse
-
#initialize(port: nil, bearer_token: nil, permitted_hosts: [], prefix: '') ⇒ Server
constructor
Initializes the server configuration.
-
#register_route(verb, path, options = {}, &block) ⇒ Object
Core routing logic: auth validation, param parsing, and block execution.
-
#run! ⇒ Object
Starts the Sinatra server with a custom GR banner.
Constructor Details
#initialize(port: nil, bearer_token: nil, permitted_hosts: [], prefix: '') ⇒ Server
Initializes the server configuration.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/gr_api_manager.rb', line 10 def initialize(port: nil, bearer_token: nil, permitted_hosts: [], prefix: '') @port = port || ENV['PORT'] || 4000 @token = bearer_token || ENV['API_TOKEN'] @permitted_hosts = permitted_hosts.empty? ? [] : permitted_hosts @prefix = prefix @app_class = Class.new(Sinatra::Base) do # Logs HTTP requests with status-based color coding. def log_request(method, path, params, status_code) color = status_code.between?(200, 299) ? "\e[32m" : "\e[31m" puts "[#{Time.now.strftime('%H:%M:%S')}] #{color}#{method} #{path} - #{status_code}\e[0m" end # Casts string URL parameters to native Ruby types (Integer, Float, Boolean). def smart_parse(hash) hash.transform_values do |val| case val when 'true' then true when 'false' then false when /^[0-9]+$/ then val.to_i when /^[0-9]+\.[0-9]+$/ then val.to_f else val end end end end configure_app end |
Instance Attribute Details
#app_class ⇒ Object (readonly)
Returns the value of attribute app_class.
7 8 9 |
# File 'lib/gr_api_manager.rb', line 7 def app_class @app_class end |
Instance Method Details
#register_route(verb, path, options = {}, &block) ⇒ Object
Core routing logic: auth validation, param parsing, and block execution.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/gr_api_manager.rb', line 88 def register_route(verb, path, = {}, &block) verb = verb.to_s.upcase require_auth = .fetch(:auth, true) required_params = .fetch(:requires, []) # Construct the full path with the optional prefix. full_path = File.join('/', @prefix.to_s, path.to_s).gsub(%r{/+}, '/') handler = proc do # 1. Authentication check if require_auth auth_header = request.env["HTTP_AUTHORIZATION"] halt 401, { error: "Token required. Format: 'Bearer <token>'" }.to_json if auth_header.nil? halt 403, { error: "Invalid token" }.to_json if auth_header.split(" ").last != settings.token end # 2. Body parsing (for POST/PUT requests) parsed_body = {} if ['POST', 'PUT'].include?(verb) body_data = request.body.read.to_s unless body_data.empty? begin parsed_body = JSON.parse(body_data, symbolize_names: true) rescue JSON::ParserError halt 400, { error: "Invalid JSON body" }.to_json end end end # 3. Merge query parameters with parsed JSON body all_params = smart_parse(params).merge(parsed_body) # 4. Declarative parameter validation missing = required_params.select { |p| all_params[p.to_sym].nil? || all_params[p.to_sym].to_s.strip.empty? } if missing.any? status 400 log_request(verb, full_path, all_params, 400) next { error: "Missing required parameters", required: missing }.to_json end # 5. Execute user-defined block result = instance_exec(all_params, &block) log_request(verb, full_path, all_params, response.status) result.to_json end @app_class.send(verb.downcase, full_path, &handler) end |
#run! ⇒ Object
Starts the Sinatra server with a custom GR banner.
139 140 141 142 143 144 145 146 147 |
# File 'lib/gr_api_manager.rb', line 139 def run! puts "=============================================" puts " GR API MANAGER STARTED" puts " Port : #{@port}" puts " Auth : #{@token ? 'Enabled' : 'Public'}" puts " Prefix : #{@prefix.empty? ? '/' : @prefix}" puts "=============================================" @app_class.run! end |