Encorda automaticamente a saída do rack com JSON quando o tipo conteúdo é aplicativo/JSON

StackOverflow https://stackoverflow.com/questions/3423905

Pergunta

Eu tenho um aplicativo Sinatra modular e gostaria de codificar a saída como JSON quando o tipo de conteúdo ditar. No momento estou fazendo isso manualmente em minhas rotas:

get 'someroute' do
    # content-type is actually set with a before filter
    # included only for clarity
    content_type 'application/json', :charset => 'utf-8'
    # .. #
    {:success=>true}.to_json
end

Eu preferiria que pareça assim:

get 'someroute' do
    content_type 'application/json', :charset => 'utf-8'
    # .. #
    {:success=>true}
end

E eu gostaria de usar o middleware do rack para fazer a codificação se ele detectar o tipo de conteúdo apropriado.

Eu tenho tentado fazer com que o seguinte funcione, mas sem sucesso (o comprimento do conteúdo é Borked-retorna o comprimento do conteúdo do conteúdo original e não o conteúdo codificado da JSON):

require 'init'

module Rack
  class JSON
    def initialize app
      @app = app
    end
    def call env
      @status, @headers, @body = @app.call env
      if json_response?
        @body = @body.to_json
      end
      [@status, @headers, @body]
    end
    def json_response?
      @headers['Content-Type'] == 'application/json'
    end
  end
end

use Rack::JSON

MyApp.set :run, false
MyApp.set :environment, ENV['RACK_ENV'].to_sym

run MyApp

Algum indicador para me levar de volta aos trilhos?

Foi útil?

Solução

Você tem tudo certo, mas uma coisa: o rack espera que o corpo seja um objeto que responda a each mas não é uma string. Basta colocar seu corpo dentro de uma matriz.

Provavelmente não é necessário, mas se você deseja definir o comprimento do conteúdo manualmente, basta adicioná -lo aos cabeçalhos.

if json_response?
  @body = [@body.to_json]
  @headers["Content-Length"] = @body[0].size.to_s
end
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top