require 'action_view' require 'action_controller' require 'action_controller/log_subscriber' module ActionController # API Controller is a lightweight version of ActionController::Base, # created for applications that don't require all functionality that a complete # \Rails controller provides, allowing you to create faster controllers for # example for API only applications. # # An API Controller is different from a normal controller in the sense that # by default it doesn't include a number of features that are usually required # by browser access only: layouts and templates rendering, cookies, sessions, # flash, assets, and so on. This makes the entire controller stack thinner and # faster, suitable for API applications. It doesn't mean you won't have such # features if you need them: they're all available for you to include in # your application, they're just not part of the default API Controller stack. # # By default, only the ApplicationController in a \Rails application inherits # from ActionController::API. All other controllers in turn inherit # from ApplicationController. # # A sample controller could look like this: # # class PostsController < ApplicationController # def index # @posts = Post.all # render json: @posts # end # end # # Request, response and parameters objects all work the exact same way as # ActionController::Base. # # == Renders # # The default API Controller stack includes all renderers, which means you # can use render :json and brothers freely in your controllers. Keep # in mind that templates are not going to be rendered, so you need to ensure # your controller is calling either render or redirect in # all actions. # # def show # @post = Post.find(params[:id]) # render json: @post # end # # == Redirects # # Redirects are used to move from one action to another. You can use the # redirect method in your controllers in the same way as # ActionController::Base. For example: # # def create # redirect_to root_url and return if not_authorized? # # do stuff here # end # # == Adding new behavior # # In some scenarios you may want to add back some functionality provided by # ActionController::Base that is not present by default in # ActionController::API, for instance MimeResponds. This # module gives you the respond_to and respond_with methods. # Adding it is quite simple, you just need to include the module in a specific # controller or in ApplicationController in case you want it # available to your entire app: # # class ApplicationController < ActionController::API # include ActionController::MimeResponds # end # # class PostsController < ApplicationController # respond_to :json, :xml # # def index # @posts = Post.all # respond_with @posts # end # end # # Quite straightforward. Make sure to check ActionController::Base # available modules if you want to include any other functionality that is # not provided by ActionController::API out of the box. class API < Metal abstract! module Compatibility def cache_store; end def cache_store=(*); end def assets_dir=(*); end def javascripts_dir=(*); end def stylesheets_dir=(*); end def page_cache_directory=(*); end def asset_path=(*); end def asset_host=(*); end def relative_url_root=(*); end def perform_caching=(*); end def helpers_path=(*); end def allow_forgery_protection=(*); end def helper_method(*); end def helper(*); end end extend Compatibility # Shortcut helper that returns all the ActionController::API modules except the ones passed in the argument: # # class MetalController # ActionController::API.without_modules(:Redirecting, :DataStreaming).each do |left| # include left # end # end # # This gives better control over what you want to exclude and makes it easier # to create an api controller class, instead of listing the modules required manually. def self.without_modules(*modules) modules = modules.map do |m| m.is_a?(Symbol) ? ActionController.const_get(m) : m end MODULES - modules end MODULES = [ AbstractController::Rendering, UrlFor, Redirecting, ApiRendering, Renderers::All, ConditionalGet, RackDelegation, StrongParameters, ForceSSL, DataStreaming, # Before callbacks should also be executed the earliest as possible, so # also include them at the bottom. AbstractController::Callbacks, # Append rescue at the bottom to wrap as much as possible. Rescue, # Add instrumentations hooks at the bottom, to ensure they instrument # all the methods properly. Instrumentation ] MODULES.each do |mod| include mod end ActiveSupport.run_load_hooks(:action_controller, self) end end