Codifica automaticamente l'output del rack con JSON quando il tipo di contenuto è application/json
-
26-09-2019 - |
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?
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