I have a Rails app provides both website and api.
I don't want some elements appear in API's middleware stack, for example : ActionDispatch::Cookies
, ActionDispatch::Session::CookieStore
or ActionDispatch::Flash
.
Website's middleware stack is remain as normal.
So how could I do that? Thanks.
I had exactly the same situation, and wanted to do the same thing. So far I have been able to use a Rails Engine to add middleware that is missing without problems for certain routes (although it is not necessarily in the "right order" in the stack, but so far it seems to be working okay):
application.rb:
# after Bundler.require(...)
require_relative '../lib/engines/website/lib/website'
lib/engines/website/lib/website.rb:
require_relative "website/engine"
module Website; end
lib/engines/website/lib/website/engine.rb:
module Website
class Engine < ::Rails::Engine
middleware.use ActionDispatch::Cookies
middleware.use ActionDispatch::Session::CookieStore
middleware.use ActionDispatch::Flash
end
end
config/routes.rb:
mount Website::Engine => "/website"
(or you can mount at "/", but define your other routes first in that case)
And everything for the website goes in the typical directory structure under the engine directory:
lib
engines
website
app
assets
...
controllers
...
views
...
config
routes.rb
lib
website
website.rb
I haven't gotten very far yet, but so far this is working for me.
Note: Technically, the engine file doesn't even have to be a separate file in the website directory. You could just shove it into website.rb
and make it a one-file-wonder if there's nothing else particularly complicated to add to your lib directory. The only requirement I've found is that the file does have to be in a lib
directory inside the engine's own named directory (theoretically containing config/routes.rb
and the rest of the engine's file structure), because when a Rails::Engine is eager-loaded by the app, the engine looks for its lib
directory to find the adjacent app, config, vendor, etc. to eager-load.