在我的heroku RoR应用程序中,我有一个控制器,我支持JSON请求。我有以下功能:
def mssg_as_json
@message = Message.new
@message.text = params.require(:messages)
@message.save
string = "http://link.com/"
@message.url = string + @message.id.to_s
@message.save
render json: { url: @message[:url] }
end
def return_mssg_as_json
if @message = Message.find_by(id: params[:id])
render json: { message: @message[:text] }
else
render json: {errors: :not_found}, status: :not_found
end
end
我也想支持XML请求。我的想法是以某种方式将XML转换为JSON,但我不知道如何。如何修改代码以支持XML和JSON?
P.S。 我的路线是:
get "messages/api" => "messages#return_mssg_as_json"
post "messages/api" => "messages#mssg_as_json"
请求发送到main_url / messages / api
答案 0 :(得分:4)
因此,您应该利用标准路线和行动。在routes.rb
中,您可以执行以下操作:
Rails.application.routes.draw do
resources :messages
namespace :api, defaults: {format: 'json'} do
namespace :v1 do
resources :messages
end
end
end
请注意,您的控制器现在嵌套在api/v1
内。这允许您将路径标识为api并随时间维护版本。这种坚实的做法。另请注意,您的网络应用程序有一个标准的messages
资源。
然后,您的控制器将如下所示:
class Api::V1::MessagesController < Api::V1::BaseController
def create
@message = Message.new(message_params)
respond_to do |format|
if @message.save
@message.update(url: "http://link.com/#{@message.id}")
format.json { render json: create_hsh, status: :ok }
format.xml { render xml: create_hsh, staus: :ok }
else
format.json { render json: @message.errors, status: :unprocessable_entity }
format.xml { render xml: @message.errors, status: :unprocessable_entity }
end
end
end
def show
respond_to do |format|
if @message = Message.find_by(id: params[:id])
format.json { render json: show_hsh, status: :ok }
format.xml { render xml: show_hsh, status: :ok }
else
format.json { render json: {errors: :not_found}, status: :not_found }
format.xml { render xml: {errors: :not_found}, status: :not_found }
end
end
end
private
def create_hsh
@message.attributes.with_indifferent_access.slice(:url)
end
def show_hsh
attr = @message.attributes.with_indifferent_access
attr.slice(:foo, :bar).merge!(message: attr[:text])
end
def message_params
params.require(:message).permit(:text)
end
end
请注意,此控制器继承自Api::V1::BaseController
。这将是您设置为执行与api相关的客户端身份验证(密钥/令牌检查等)的控制器。也许,有点像:
class Api::V1::BaseController < ActionController::API
before_action :authorize
def authorize
# do your checks in a way that results in a variable @authorized?
render(json: {errors: :unauthorized}, status: :unauthorized) unless @authorized?
end
end
因此,现在您正在使用单个控制器操作来响应所有格式类型(您选择提供)。然后,您的客户会发布类似的内容:
http://your.api.com/messages.json
获得json响应。或者:
http://your.api.com/messages.xml
获取xml响应。你可能会注意到这一点:namespace :api, defaults: {format: 'json'} do
。这意味着您的客户可以致电:
http://your.api.com/messages
,默认为json
格式。
现在你没有一堆随机端点(比如mssg_as_json
),只有你的客户期望的常规RESTful端点。您的API客户会非常喜欢您。
您会注意到show_hsh
是您之前提问的代码。