web-dev-qa-db-fra.com

Comment analyser une seule fois le corps de la requête JSON dans Sinatra et l'exposer à toutes les routes?

J'écris une API et elle reçoit une charge utile JSON comme corps de demande.

Pour y arriver actuellement, je fais quelque chose comme ceci:

post '/doSomething' do
    request.body.rewind
    request_payload = JSON.parse request.body.read

    #do something with request_payload
    body request_payload['someKey']
end

Quelle est la bonne façon de résumer cela afin de ne pas avoir à le faire pour chaque itinéraire? Certains de mes itinéraires sont plus compliqués que cela, et par conséquent, la demande.l'objet serait relu et réanalysé plusieurs fois par itinéraire avec cette approche, ce que je veux éviter.

Existe-t-il un moyen de rendre la demande_payload accessible par magie aux itinéraires? Comme ça:

post '/doSomething' do
    #do something with request_payload, it's already parsed and available
    body request_payload['someKey']
end
31
lms

Utilisez un sinatra avant le gestionnaire:

before do
  request.body.rewind
  @request_payload = JSON.parse request.body.read
end

cela l'exposera au gestionnaire de requêtes actuel. Si vous voulez qu'il soit exposé à tous les gestionnaires, mettez-le dans une superclasse et étendez cette classe dans vos gestionnaires.

55
mcfinnigan

Vous pouvez également utiliser Rack Middleware pour l'analyser. Voir https://github.com/rack/rack-contrib Juste use Rack::PostBodyContentTypeParser lors de l'initialisation de votre classe Sinatra.

7
Harper Maddox

Comme ça, travailler pour Sinatra 1.4.5

before do
  if request.body.size > 0
    request.body.rewind
    @params = ActiveSupport::JSON.decode(request.body.read)
  end
end
5
Pavel Evstigneev
before do
  request.body.rewind
  @request_payload = JSON.parse(request.body.read, symbolize_names: true)
end

Ainsi, vous pouvez également symboliser les noms lors de l'analyse du corps de la requête JSON, cela vous donnera accès à vos paramètres imbriqués comme ceci @request_payload[:user]

0
Serj Petrenko