mirror of
https://github.com/hakanensari/frankfurter.git
synced 2024-11-22 02:52:49 +01:00
Switch to Roda
A first stab at replacing Sinatra with Roda
This commit is contained in:
parent
535471509b
commit
82666af2d6
@ -1,7 +1,7 @@
|
|||||||
Metrics/AbcSize:
|
Metrics/AbcSize:
|
||||||
Max: 21.79
|
Max: 21.79
|
||||||
Metrics/BlockLength:
|
Metrics/BlockLength:
|
||||||
ExcludedMethods: ['describe', 'helpers']
|
ExcludedMethods: ['describe', 'route']
|
||||||
Metrics/MethodLength:
|
Metrics/MethodLength:
|
||||||
Max: 13
|
Max: 13
|
||||||
Minitest:
|
Minitest:
|
||||||
|
3
Gemfile
3
Gemfile
@ -7,11 +7,12 @@ ruby '2.7.1'
|
|||||||
gem 'money'
|
gem 'money'
|
||||||
gem 'oj'
|
gem 'oj'
|
||||||
gem 'ox'
|
gem 'ox'
|
||||||
|
gem 'rack-contrib'
|
||||||
gem 'rack-cors'
|
gem 'rack-cors'
|
||||||
gem 'rake'
|
gem 'rake'
|
||||||
|
gem 'roda'
|
||||||
gem 'rufus-scheduler'
|
gem 'rufus-scheduler'
|
||||||
gem 'sequel_pg'
|
gem 'sequel_pg'
|
||||||
gem 'sinatra'
|
|
||||||
gem 'unicorn'
|
gem 'unicorn'
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
18
Gemfile.lock
18
Gemfile.lock
@ -25,8 +25,6 @@ GEM
|
|||||||
minitest (>= 4, < 6)
|
minitest (>= 4, < 6)
|
||||||
money (6.13.7)
|
money (6.13.7)
|
||||||
i18n (>= 0.6.4, <= 2)
|
i18n (>= 0.6.4, <= 2)
|
||||||
mustermann (1.1.1)
|
|
||||||
ruby2_keywords (~> 0.0.1)
|
|
||||||
oj (3.10.6)
|
oj (3.10.6)
|
||||||
ox (2.13.2)
|
ox (2.13.2)
|
||||||
parallel (1.19.1)
|
parallel (1.19.1)
|
||||||
@ -36,16 +34,18 @@ GEM
|
|||||||
public_suffix (4.0.4)
|
public_suffix (4.0.4)
|
||||||
raabro (1.1.6)
|
raabro (1.1.6)
|
||||||
rack (2.2.2)
|
rack (2.2.2)
|
||||||
|
rack-contrib (2.2.0)
|
||||||
|
rack (~> 2.0)
|
||||||
rack-cors (1.1.1)
|
rack-cors (1.1.1)
|
||||||
rack (>= 2.0.0)
|
rack (>= 2.0.0)
|
||||||
rack-protection (2.0.8.1)
|
|
||||||
rack
|
|
||||||
rack-test (1.1.0)
|
rack-test (1.1.0)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
rainbow (3.0.0)
|
rainbow (3.0.0)
|
||||||
raindrops (0.19.1)
|
raindrops (0.19.1)
|
||||||
rake (13.0.1)
|
rake (13.0.1)
|
||||||
rexml (3.2.4)
|
rexml (3.2.4)
|
||||||
|
roda (3.31.0)
|
||||||
|
rack
|
||||||
rubocop (0.82.0)
|
rubocop (0.82.0)
|
||||||
jaro_winkler (~> 1.5.1)
|
jaro_winkler (~> 1.5.1)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
@ -61,7 +61,6 @@ GEM
|
|||||||
rubocop-sequel (0.0.6)
|
rubocop-sequel (0.0.6)
|
||||||
rubocop (~> 0.55, >= 0.55)
|
rubocop (~> 0.55, >= 0.55)
|
||||||
ruby-progressbar (1.10.1)
|
ruby-progressbar (1.10.1)
|
||||||
ruby2_keywords (0.0.2)
|
|
||||||
rufus-scheduler (3.6.0)
|
rufus-scheduler (3.6.0)
|
||||||
fugit (~> 1.1, >= 1.1.6)
|
fugit (~> 1.1, >= 1.1.6)
|
||||||
safe_yaml (1.0.5)
|
safe_yaml (1.0.5)
|
||||||
@ -73,12 +72,6 @@ GEM
|
|||||||
docile (~> 1.1)
|
docile (~> 1.1)
|
||||||
simplecov-html (~> 0.11)
|
simplecov-html (~> 0.11)
|
||||||
simplecov-html (0.12.2)
|
simplecov-html (0.12.2)
|
||||||
sinatra (2.0.8.1)
|
|
||||||
mustermann (~> 1.0)
|
|
||||||
rack (~> 2.0)
|
|
||||||
rack-protection (= 2.0.8.1)
|
|
||||||
tilt (~> 2.0)
|
|
||||||
tilt (2.0.10)
|
|
||||||
tzinfo (2.0.2)
|
tzinfo (2.0.2)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
unicode-display_width (1.7.0)
|
unicode-display_width (1.7.0)
|
||||||
@ -101,16 +94,17 @@ DEPENDENCIES
|
|||||||
money
|
money
|
||||||
oj
|
oj
|
||||||
ox
|
ox
|
||||||
|
rack-contrib
|
||||||
rack-cors
|
rack-cors
|
||||||
rack-test
|
rack-test
|
||||||
rake
|
rake
|
||||||
|
roda
|
||||||
rubocop-minitest
|
rubocop-minitest
|
||||||
rubocop-performance
|
rubocop-performance
|
||||||
rubocop-sequel
|
rubocop-sequel
|
||||||
rufus-scheduler
|
rufus-scheduler
|
||||||
sequel_pg
|
sequel_pg
|
||||||
simplecov
|
simplecov
|
||||||
sinatra
|
|
||||||
unicorn
|
unicorn
|
||||||
vcr
|
vcr
|
||||||
webmock
|
webmock
|
||||||
|
@ -3,4 +3,4 @@
|
|||||||
require './config/environment'
|
require './config/environment'
|
||||||
require 'web/server'
|
require 'web/server'
|
||||||
|
|
||||||
run Sinatra::Application
|
run Web::Server.freeze.app
|
||||||
|
@ -1,103 +1,93 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'oj'
|
require 'oj'
|
||||||
|
require 'rack/contrib/jsonp'
|
||||||
require 'rack/cors'
|
require 'rack/cors'
|
||||||
require 'sinatra'
|
require 'roda'
|
||||||
|
|
||||||
require 'currency_names'
|
require 'currency_names'
|
||||||
require 'query'
|
require 'query'
|
||||||
require 'quote'
|
require 'quote'
|
||||||
|
|
||||||
|
module Web
|
||||||
|
class Server < Roda
|
||||||
use Rack::Cors do
|
use Rack::Cors do
|
||||||
allow do
|
allow do
|
||||||
origins '*'
|
origins '*'
|
||||||
resource '*', headers: :any, methods: :get
|
resource '*', headers: :any, methods: %i[get options]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
use Rack::JSONP
|
||||||
|
|
||||||
|
plugin :caching
|
||||||
|
|
||||||
|
plugin :error_handler do |_error|
|
||||||
|
request.halt [422, {}, nil]
|
||||||
|
end
|
||||||
|
|
||||||
|
plugin :indifferent_params
|
||||||
|
|
||||||
|
plugin :json, content_type: 'application/json; charset=utf-8',
|
||||||
|
serializer: ->(o) { Oj.dump(o, mode: :compat) }
|
||||||
|
|
||||||
|
plugin :params_capturing
|
||||||
|
|
||||||
|
route do |r|
|
||||||
|
r.root do
|
||||||
|
{ docs: 'https://www.frankfurter.app/docs' }
|
||||||
|
end
|
||||||
|
|
||||||
|
r.is(/latest|current/) do
|
||||||
|
r.params['date'] = Date.today.to_s
|
||||||
|
quote = quote_end_of_day(r)
|
||||||
|
r.etag quote.cache_key
|
||||||
|
|
||||||
|
quote.formatted
|
||||||
|
end
|
||||||
|
|
||||||
|
r.is(/(\d{4}-\d{2}-\d{2})/) do
|
||||||
|
r.params['date'] = r.params['captures'].first
|
||||||
|
quote = quote_end_of_day(r)
|
||||||
|
r.etag quote.cache_key
|
||||||
|
|
||||||
|
quote.formatted
|
||||||
|
end
|
||||||
|
|
||||||
|
r.is(/(\d{4}-\d{2}-\d{2})\.\.(\d{4}-\d{2}-\d{2})?/) do
|
||||||
|
r.params['start_date'] = r.params['captures'].first
|
||||||
|
r.params['end_date'] = r.params['captures'][1] || Date.today.to_s
|
||||||
|
quote = quote_interval(r)
|
||||||
|
r.etag quote.cache_key
|
||||||
|
|
||||||
|
quote.formatted
|
||||||
|
end
|
||||||
|
|
||||||
|
r.is 'currencies' do
|
||||||
|
currency_names = CurrencyNames.new
|
||||||
|
r.etag currency_names.cache_key
|
||||||
|
|
||||||
|
currency_names.formatted
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
configure :development do
|
private
|
||||||
set :show_exceptions, :after_handler
|
|
||||||
end
|
|
||||||
|
|
||||||
configure :production do
|
def quote_end_of_day(request)
|
||||||
disable :dump_errors
|
query = Query.build(request.params)
|
||||||
end
|
|
||||||
|
|
||||||
configure :test do
|
|
||||||
set :raise_errors, false
|
|
||||||
end
|
|
||||||
|
|
||||||
set :static_cache_control, [:public, max_age: 300]
|
|
||||||
|
|
||||||
helpers do
|
|
||||||
def end_of_day_quote
|
|
||||||
@end_of_day_quote ||= begin
|
|
||||||
query = Query.build(params)
|
|
||||||
quote = Quote::EndOfDay.new(**query)
|
quote = Quote::EndOfDay.new(**query)
|
||||||
quote.perform
|
quote.perform
|
||||||
halt 404 if quote.not_found?
|
request.halt [404, {}, nil] if quote.not_found?
|
||||||
|
|
||||||
quote
|
quote
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def interval_quote
|
def quote_interval(request)
|
||||||
@interval_quote ||= begin
|
query = Query.build(request.params)
|
||||||
query = Query.build(params)
|
|
||||||
quote = Quote::Interval.new(**query)
|
quote = Quote::Interval.new(**query)
|
||||||
quote.perform
|
quote.perform
|
||||||
halt 404 if quote.not_found?
|
request.halt [404, {}, nil] if quote.not_found?
|
||||||
|
|
||||||
quote
|
quote
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def json(data)
|
|
||||||
json = Oj.dump(data, mode: :compat)
|
|
||||||
callback = params['callback']
|
|
||||||
|
|
||||||
if callback
|
|
||||||
content_type :js, charset: Encoding::UTF_8
|
|
||||||
"#{callback}(#{json})"
|
|
||||||
else
|
|
||||||
content_type :json, charset: Encoding::UTF_8
|
|
||||||
json
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/' do
|
|
||||||
json({ docs: 'https://www.frankfurter.app/docs' })
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/(?:latest|current)', mustermann_opts: { type: :regexp } do
|
|
||||||
params[:date] = Date.today.to_s
|
|
||||||
etag end_of_day_quote.cache_key
|
|
||||||
json end_of_day_quote.formatted
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/(?<date>\d{4}-\d{2}-\d{2})', mustermann_opts: { type: :regexp } do
|
|
||||||
etag end_of_day_quote.cache_key
|
|
||||||
json end_of_day_quote.formatted
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/(?<start_date>\d{4}-\d{2}-\d{2})\.\.(?<end_date>\d{4}-\d{2}-\d{2})?',
|
|
||||||
mustermann_opts: { type: :regexp } do
|
|
||||||
@params[:end_date] ||= Date.today.to_s
|
|
||||||
etag interval_quote.cache_key
|
|
||||||
json interval_quote.formatted
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/currencies' do
|
|
||||||
currency_names = CurrencyNames.new
|
|
||||||
etag currency_names.cache_key
|
|
||||||
json currency_names.formatted
|
|
||||||
end
|
|
||||||
|
|
||||||
not_found do
|
|
||||||
halt 404
|
|
||||||
end
|
|
||||||
|
|
||||||
error do
|
|
||||||
halt 422
|
|
||||||
end
|
end
|
||||||
|
@ -7,7 +7,7 @@ require 'web/server'
|
|||||||
describe 'the server' do
|
describe 'the server' do
|
||||||
include Rack::Test::Methods
|
include Rack::Test::Methods
|
||||||
|
|
||||||
let(:app) { Sinatra::Application }
|
let(:app) { Web::Server.freeze }
|
||||||
|
|
||||||
def json
|
def json
|
||||||
Oj.load(last_response.body)
|
Oj.load(last_response.body)
|
||||||
|
@ -7,7 +7,7 @@ require 'web/server'
|
|||||||
describe 'the server' do
|
describe 'the server' do
|
||||||
include Rack::Test::Methods
|
include Rack::Test::Methods
|
||||||
|
|
||||||
let(:app) { Sinatra::Application }
|
let(:app) { Web::Server.freeze }
|
||||||
let(:json) { Oj.load(last_response.body) }
|
let(:json) { Oj.load(last_response.body) }
|
||||||
let(:headers) { last_response.headers }
|
let(:headers) { last_response.headers }
|
||||||
|
|
||||||
@ -100,11 +100,11 @@ describe 'the server' do
|
|||||||
|
|
||||||
it 'handles JSONP' do
|
it 'handles JSONP' do
|
||||||
get '/latest?callback=foo'
|
get '/latest?callback=foo'
|
||||||
_(last_response.body).must_be :start_with?, 'foo'
|
_(last_response.body).must_be :start_with?, '/**/foo'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets charset to UTF-8' do
|
it 'sets charset to utf-8' do
|
||||||
get '/currencies'
|
get '/currencies'
|
||||||
_(last_response.headers['content-type']).must_be :end_with?, 'charset=UTF-8'
|
_(last_response.headers['content-type']).must_be :end_with?, 'charset=utf-8'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user