在ROR中为JSON处理函数添加XML支持

时间:2017-11-03 18:58:41

标签: ruby-on-rails json ruby xml heroku

在我的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

1 个答案:

答案 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是您之前提问的代码。