Skip to content
This repository was archived by the owner on Oct 20, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apiculture.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ Gem::Specification.new do |s|
s.add_development_dependency "rake", ">= 12.3.3"
s.add_development_dependency "bundler", "~> 1.0"
s.add_development_dependency "simplecov", ">= 0"
s.add_development_dependency "rack-parser"
end
25 changes: 13 additions & 12 deletions lib/apiculture/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
class Apiculture::App

class << self
def use(middlreware_factory, middleware_options, &middleware_blk)
def use(middleware, *args, &block)
@middleware_configurations ||= []
@middleware_configurations << [middleware_factory, middleware_options, middleware_blk]
@middleware_configurations << [middleware, args, block]
end

def middleware_configurations
Expand Down Expand Up @@ -36,6 +36,17 @@ def define_action(http_method, url_path, **options, &handler_blk)
@actions ||= []
@actions << [http_method.to_s.upcase, url_path, options, handler_blk]
end

def call(env)
app = new
middleware_configurations = @middleware_configurations || []
Rack::Builder.new do
middleware_configurations.each do |middleware, *args, &block|
use(middleware, *args, &block)
end
run ->(env) { app.call_without_middleware(env) }
end.to_app.call(env)
end
end

def call_without_middleware(env)
Expand Down Expand Up @@ -69,16 +80,6 @@ def call_without_middleware(env)
[404, {'Content-Type' => 'application/json', 'Content-Length' => out.bytesize.to_s}, [out]]
end

def self.call(env)
app = new
Rack::Builder.new do
(@middleware_configurations || []).each do |middleware_args|
use(*middleware_args)
end
run ->(env) { app.call_without_middleware(env) }
end.to_app.call(env)
end

attr_reader :request
attr_reader :env
attr_reader :params
Expand Down
35 changes: 32 additions & 3 deletions spec/apiculture_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,48 @@ def app
}.to raise_error('Missing parameter :name')
end

it 'verifies the parameter type' do
it 'verifies the parameter type and allows addition of middleware' do
require 'rack/parser'
@app_class = Class.new(Apiculture::App) do
extend Apiculture
use Rack::Parser

required_param :number, "Number of the thing", Integer
api_method :post, '/thing' do
raise "Should never be called"
raise "Did end up in the action"
end
end

expect {
post '/thing', {number: '123'}
post '/thing', JSON.dump({number: '123'}), {'CONTENT_TYPE' => 'application/json'}
}.to raise_error('Received String, expected Integer for :number')

expect {
post '/thing', JSON.dump({number: 123}), {'CONTENT_TYPE' => 'application/json'}
}.to raise_error(/Did end up in the action/)
end

it 'allows addition of middleware' do
class Raiser < Struct.new(:app)
def call(env)
s, h, b = app.call(env)
h['X-Via'] = 'Raiser'
[s, h, b]
end
end

@app_class = Class.new(Apiculture::App) do
extend Apiculture
use Raiser

api_method :post, '/thing' do
'Everything is fine'
end
end

post '/thing'

raise last_response.headers.inspect
end

it 'supports an arbitrary object with === as a type specifier for a parameter' do
Expand Down