J'ai une API écrite dans Rails qui, à chaque demande, répond par une réponse JSON.
La réponse pourrait être énorme, je dois donc compresser la réponse JSON avec gzip.
Vous vous demandez comment faire cela dans le contrôleur Rails?
J'ai ajouté la ligne
use Rack::Deflater
dans config.ru
Devrais-je également changer quelque chose dans la ligne qui rend JSON?
render :json => response.to_json()
Aussi, comment puis-je vérifier si la réponse est au format gzip ou non .. ??
J'ai fait une requête curl du terminal, je ne vois que le JSON normal.
Pour que la réponse soit au format gzip, nous n'avons pas besoin de changer l'appel de méthode render
.
Si la requête comporte l'en-tête Accept-Encoding: gzip
, Rails compresse automatiquement la réponse JSON à l'aide de gzip.
Si vous ne souhaitez pas que l'utilisateur envoie une demande avec un en-tête prédéfini, vous pouvez ajouter l'en-tête à la demande manuellement dans le contrôleur avant de générer la réponse:
request.env['HTTP_ACCEPT_ENCODING'] = 'gzip'
render :json => response.to_json()
Mon post Compression de contenu avec Rack :: Deflater décrit plusieurs façons d'intégrer Rack :: Deflater. Le plus simple serait de mettre à jour config/application.rb
avec:
module YourApp
class Application < Rails::Application
config.middleware.use Rack::Deflater
end
end
et vous compresserez automatiquement toutes les réponses du contrôleur avec deflate/gzip si le client dit explicitement qu'il peut le gérer.
Vous pouvez interroger Curl en définissant un en-tête personnalisé pour obtenir une réponse compressée.
$ curl -H "Accept-Encoding: gzip, deflate" localhost:3000/posts.json > posts_json.gz
puis, décompressez-le pour afficher la réponse réelle json
$ gzip -d posts_json.gz
$ cat posts_json
Si ça ne marche pas. postez de nouveau avec la sortie de rake middlewares
pour nous aider à résoudre les problèmes.
Dans certains cas, vous pouvez envisager d'écrire une réponse énorme dans un fichier et de le gzip:
res = {} # huge data hash
json = res.to_json
Zlib::GzipWriter.open('public/api/huge_data.json.gz') { |gz| gz.write json }
et mettre à jour ce fichier régulièrement