Codifica automaticamente l'output del rack con JSON quando il tipo di contenuto è application/json

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

Domanda

Ho un'app Sinatra modulare e vorrei codificare l'output come JSON quando richiesto dal tipo di contenuto.Al momento lo sto facendo manualmente nei miei percorsi:

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

Preferirei che fosse così:

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

E mi piacerebbe utilizzare il middleware Rack per eseguire la codifica se rileva il tipo di contenuto appropriato.

Ho provato a far funzionare quanto segue, ma senza alcun risultato (la lunghezza del contenuto viene interrotta: restituisce la lunghezza del contenuto del contenuto originale e non del contenuto codificato 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

Qualche indicazione per rimettermi in carreggiata?

È stato utile?

Soluzione

Hai ragione, tranne una cosa:Rack si aspetta che il corpo sia un oggetto a cui risponde each ma non è una stringa.Metti semplicemente il tuo corpo all'interno di un array.

Probabilmente non è necessario, ma se vuoi impostare manualmente la lunghezza del contenuto, aggiungilo semplicemente alle intestazioni.

if json_response?
  @body = [@body.to_json]
  @headers["Content-Length"] = @body[0].size.to_s
end
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top