- Adopted Rack 3. Technically, just lower the cases for headers.
- Internal strings are all frozen now.
log
andlog_error
now takes theenv
for the second argument, rather than the error stream.handle
now takes theenv
for the third argument, rather than the error stream.
- The default error logging will now also show
env['PATH_INFO']
.
- Fixed
Jellyfish::Rewrite
for SCRIPT_NAME when host is also used.
- Interface for
Builder.app
, andBuilder#to_app
, andRewrite.new
slightly changed due to fixing the bug inRewrite
. You shouldn't use those directly though. - Now all strings allocated from Jellyfish are frozen.
- Fixed
Jellyfish::Rewrite
. Should properly handle SCRIPT_NAME.
- Fixed
Jellyfish::Rewrite
. Should put rewritten path in the front.
- Fixed mapping with host in some cases (longest match goes first)
- Fixed scheme matching with https. Now it won't try to map against https
because it's not that easy to implement and this is how
Rack::URLMap
works anyway.
Jellyfish::NewRelic
is extracted to jellyfish-contrib
Jellyfish::URLMap
would now properly handle nested maps likeRack::URLMap
.
Jellyfish::URLMap
now supports listening on a specific host likeRack::URLMap
. Beside prefixinghttp://
, it also supports passinghost: host
argument tomap
, and alisten
directive which takes a block.- Instead of using
module_eval
, DSL is now defined viadefine_method
to make debugging easier. Performance shouldn't get hit.
- Added
Jellyfish::Rewrite
as an extension toJellyfish::Builder
. Please check README.md for more detail.
Jellyfish::Sinatra
,Jellyfish::MultiActions
, andJellyfish::Swagger
were extracted to jellyfish-contrib
- Added
Jellyfish::Builder
andJellyfish::URLMap
which is 36 times faster thanRack::Builder
andRack::URLMap
given an application with 1000 routes.
Jellyfish::NewRelic
is fixed. Thanks Jason R. Clark (@jasonrclark)
- Now
Jellyfish.handle
could take multiple exceptions as the arguments.
- Introduced
Jellyfish::WebSocket
for basic websocket support.
- Renamed
forward
tocascade
to better aligned with Rack.
- Introduced
log
andlog_error
for for controllers. - Introduced
not_found
to trigger 404 response. - Now we separate the idea of 404 and cascade. Use
not_found
for 404 responses, andcascade
for forwarding requests.
- Now we have Jellyfish::Swagger to generate Swagger documentation. Read README.md for more detail or checkout config.ru for a full example.
- Do not rescue Exception since we don't really want to rescue something like SignalException, which would break signal handling.
- Fixed a thread safety bug for initializing exception handlers.
- We no longer use exceptions to control the flow. Use
halt(InternalError.new)
instead. However, raising exceptions would still work. Just prefer to usehalt
if you would like some performance boost.
- If you're raising
NotFound
instead of usingforward
in your app, it would no longer forward the request but show a 404 page. Always useforward
if you intend to forward the request.
- Now there's no longer Jellyfish#controller but Jellyfish.controller, as there's no much point for making the controller per-instance. You do this to override the controller method instead:
class MyApp
include Jellyfish
def self.controller
MyController
end
class MyController < Jellyfish::Controller
def hi
'hi'
end
end
get{ hi }
end
- You can also change the controller by assigning it. The same as above:
class MyApp
include Jellyfish
class MyController < Jellyfish::Controller
def hi
'hi'
end
end
controller MyController
get{ hi }
end
- Introduced Jellyfish.controller_include which makes it easy to pick modules to be included in built-in controller.
- Introduced Controller#halt as a short hand for
throw :halt
- Now default route is
//
. Usingget{ 'Hello, World!' }
is effectively the same asget(//){ 'Hello, World!' }
- Now inheritance works.
- Now it raises TypeError if passing a route doesn't respond to :match.
- Now Jellyfish would find the most suitable error handler to handle errors, i.e. It would find the error handler which would handle the nearest exception class in the ancestors chain. Previously it would only find the first one which matches, ignoring the rest. It would also cache the result upon a lookup.
-
Added
Jellyfish::ChunkedBody
which is similar toSinatra::Stream
. -
Added
Jellyfish::MultiAction
which gives you some kind of ability to do before or after filters. See README.md for usage. -
Added
Jellyfish::NormalizedParams
which gives you some kind of Sinatra flavoured params. -
Added
Jellyfish::NormalizedPath
which would unescape incoming PATH_INFO so you could match '/f%C3%B6%C3%B6' with '/föö'.
- Now
Jellyfish::Sinatra
includesJellyfish::MultiAction
,Jellyfish::NormalizedParams
, andJellyfish::NormalizedPath
.
-
Extracted Jellyfish::Controller#call and Jellyfish::Controller#block_call into Jellyfish::Controller::Call so that you can have modules which can override call and block_call. See Jellyfish::Sinatra and Jellyfish::NewRelic for an example.
-
Now you can use
request
in the controller, which is essentially:@request ||= Rack::Request.new(env)
. This also means you would need Rack installed and required to use it. Other than this, there's no strict requirement for Rack.
- Added Jellyfish::NewRelic which makes you work easier with NewRelic. Here's an example of how to use it: (extracted from README)
require 'jellyfish'
class Tank
include Jellyfish
class MyController < Jellyfish::Controller
include Jellyfish::NewRelic
end
def controller; MyController; end
get '/' do
"OK\n"
end
end
use Rack::ContentLength
use Rack::ContentType, 'text/plain'
require 'cgi' # newrelic dev mode needs this and it won't require it itself
require 'new_relic/rack/developer_mode'
use NewRelic::Rack::DeveloperMode # GET /newrelic to read stats
run Tank.new
NewRelic::Agent.manual_start(:developer_mode => true)
- Respond an empty string response if the block gives a nil.
- Added Jellyfish#log method which allow you to use the same way as Jellyfish log things.
- rescue LocalJumpError and give a hint if you're trying to
return or break from the block. You should use
next
instead. Or you can simply pass lambda which you can safelyreturn
. For example:get '/path', &lambda{ return "body" }
- Introduced
initialize_params
and only initialize them whenever it's not yet set, giving you the ability to initialize params before callingblock_call
, thus you can customize params more easily. An example for making NewRelic work would be like this:
class Controller < Api::Controller
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
def block_call argument, block
path = if argument.respond_to?(:regexp)
argument.regexp
else
argument
end.to_s[1..-1]
name = "#{env['REQUEST_METHOD']} #{path}"
initialize_params(argument) # magic category, see:
# NewRelic::MetricParser::WebTransaction::Jellyfish
perform_action_with_newrelic_trace(:category => 'Controller/Jellyfish',
:path => path ,
:name => name ,
:request => request ,
:params => params ){ super }
end
end
module NewRelic::MetricParser::WebTransaction::Jellyfish
include NewRelic::MetricParser::WebTransaction::Pattern
def is_web_transaction?; true; end
def category ; 'Jellyfish'; end
end
protect
method is removed and inlined, reducing the size of call stack.
log_error
is now a public method.
- Force params encoding to Encoding.default_external
- Removed accidentally added sinatra files.
- Some internal constants are removed.
- Renamed
Respond
toResponse
.
-
Now Jellyfish would always use the custom error handler to handle the particular exception even if
handle_exceptions
set to false. That is, now settinghandle_exceptions
to false would only disable default error handling. This behavior makes more sense since if you want the exception bubble out then you shouldn't define the custom error handler in the first place. If you define it, you must mean you want to use it. -
Eliminated some uninitialized instance variable warnings.
-
Now you can access the original app via
jellyfish
in the controller. -
Jellyfish::Controller
no longer includesJellyfish
, which would remove thoseDSL
methods accidentally included in previous version (0.4.0-).
- Now you can define your own custom controller like:
require 'jellyfish'
class Heater
include Jellyfish
get '/status' do
temperature
end
def controller; Controller; end
class Controller < Jellyfish::Controller
def temperature
"30\u{2103}\n"
end
end
end
use Rack::ContentLength
use Rack::ContentType, 'text/plain'
run Heater.new
- Now it's possible to use a custom matcher instead of regular expression:
require 'jellyfish'
class Tank
include Jellyfish
class Matcher
def match path
path.reverse == 'match/'
end
end
get Matcher.new do |match|
"#{match}\n"
end
end
use Rack::ContentLength
use Rack::ContentType, 'text/plain'
run Tank.new
- Added a Sinatra flavor controller
require 'jellyfish'
class Tank
include Jellyfish
def controller; Jellyfish::Sinatra; end
get %r{^/(?<id>\d+)$} do
"Jelly ##{params[:id]}\n"
end
end
use Rack::ContentLength
use Rack::ContentType, 'text/plain'
run Tank.new
- Birthday!