跳至内容 跳至搜索

Action Controller API

API 控制器是 ActionController::Base 的轻量级版本,专为不需要完整 Rails 控制器所有功能的应用程序而创建,允许您创建仅包含 API 应用程序所需功能的控制器。

API 控制器与普通控制器不同,默认情况下它不包含通常仅由浏览器访问所需的许多功能:布局和模板渲染、闪存、资产等等。这使得整个控制器堆栈更薄,适合 API 应用程序。但这并不意味着您在需要时无法使用这些功能:它们都可供您在应用程序中包含,只是它们不是默认 API 控制器堆栈的一部分。

通常,ApplicationController 是唯一从 ActionController::API 继承的控制器。所有其他控制器依次从 ApplicationController 继承。

一个示例控制器可能如下所示

class PostsController < ApplicationController
  def index
    posts = Post.all
    render json: posts
  end
end

请求、响应和参数对象的工作方式与 ActionController::Base 完全相同。

渲染

默认的 API 控制器堆栈包含所有渲染器,这意味着您可以在控制器中自由使用 render :json 及其兄弟。请记住,模板不会被渲染,因此您需要确保您的控制器在所有操作中都调用 renderredirect_to,否则它将返回 204 No Content

def show
  post = Post.find(params[:id])
  render json: post
end

重定向

重定向用于从一个操作移动到另一个操作。您可以在控制器中使用 redirect_to 方法,就像在 ActionController::Base 中一样。例如

def create
  redirect_to root_url and return if not_authorized?
  # do stuff here
end

添加新行为

在某些情况下,您可能希望添加由 ActionController::Base 提供但默认情况下在 ActionController::API 中不存在的一些功能,例如 MimeResponds。此模块为您提供了 respond_to 方法。添加它非常简单,您只需要在特定控制器中包含该模块,或者如果您希望它在整个应用程序中可用,则在 ApplicationController 中包含该模块。

class ApplicationController < ActionController::API
  include ActionController::MimeResponds
end

class PostsController < ApplicationController
  def index
    posts = Post.all

    respond_to do |format|
      format.json { render json: posts }
      format.xml  { render xml: posts }
    end
  end
end

如果您想使用 ActionController::API 默认情况下未提供的任何其他功能,请确保检查 ActionController::Base 中包含的模块。

方法
W

常量

MODULES = [ AbstractController::Rendering, UrlFor, Redirecting, ApiRendering, Renderers::All, ConditionalGet, BasicImplicitRender, StrongParameters, DataStreaming, DefaultHeaders, Logging, # Before 回调也应该尽早执行,所以 # 也在底部包含它们。AbstractController::Callbacks, # 在底部追加 rescue 以尽可能多地包装。Rescue, # 在底部添加 instrumentation hook,以确保它们正确地对 # 所有方法进行 instrumentation。Instrumentation, # Params wrapper 应该在 instrumentation 之前,以便它们 # 在日志中正确显示 ParamsWrapper ]
 

类公共方法

without_modules(*modules)

快捷助手,返回除作为参数传递的模块之外的所有 ActionController::API 模块。

class MyAPIBaseController < ActionController::Metal
  ActionController::API.without_modules(:UrlFor).each do |left|
    include left
  end
end

这可以更好地控制您想要排除的内容,并使创建 API 控制器类变得更容易,而不是手动列出所需的模块。

# File actionpack/lib/action_controller/api.rb, line 106
def self.without_modules(*modules)
  modules = modules.map do |m|
    m.is_a?(Symbol) ? ActionController.const_get(m) : m
  end

  MODULES - modules
end