json sinatra

El método params del controlador Sinatra está vacío en la solicitud de publicación JSON



(2)

Para responder a esta pregunta, primero tendremos que ver algunas solicitudes HTTP (que no son más que simples ''mensajes'' de telnet ; esto se puede recrear fácilmente a mano). Primero, ¿qué sucede cuando envía un <form> HTML normal? La solicitud POST se verá muy similar a esto (probablemente con algunos parámetros adicionales, pero no tenemos que preocuparnos por eso ahora):

POST /submit-form HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: 12 name=JohnDoe

Escribir ese carácter por carácter (reemplazando /sample-form con cualquiera que sea la URL para cualquier acción de formulario, y el Host con su IP o nombre de host) será lo mismo que enviaría su navegador. Lo importante para aprender de esto es la sintaxis de los parámetros: formname=formvalue . ¡Sinatra interpreta el cuerpo de la solicitud POST en el hash params usando esta sintaxis! Por lo tanto, las solicitudes JSON, al ser sustancialmente incompatibles con esto, no se mostrarán en el hash params debido a esto.

Sin embargo, lo que estás haciendo en tu bloque before muestra la solución adecuada. Si bien los params de los anteriores serían {''name'' => ''JohnDoe''} , request.body.read devolverá el cuerpo original, name=JohnDoe .

Al saber esto, uno puede llegar a entender por qué funciona su solución ''hacky'': el cuerpo original de la solicitud POST es interpretado por JSON.parse , y luego se inserta en el hash de params vacío. La razón por la que parece intrépido es que params es un intermediario innecesario en este ejemplo. Lo siguiente debe hacer el trabajo:

post ''/locations/new'' do @json = JSON.parse(request.body.read) # @json now contains a hash of the submitted JSON content end

Sin embargo, una solución que ejerza mejores prácticas solo respondería si se proporciona contenido JSON o responderá de manera diferente si se envía un formulario estándar. Como se vio en el ejemplo anterior de la solicitud HTTP POST , un formulario HTML se identifica con el tipo MIME de la application/x-www-form-urlencoded , mientras que JSON se identifica con la application/json . Si desea obtener información específica sobre la verificación del tipo MIME de la solicitud POST , consulte esta pregunta con algunas respuestas excelentes sobre cómo hacer esto con Sinatra.

Tengo una aplicación de Sinatra y en la mayoría de mis controladores json entra y se recoge automáticamente en el objeto params. Sin embargo, tengo una acción posterior que no obtiene los parámetros en absoluto a menos que juegue un truco con un método anterior para extraer la solicitud. Los parámetros de cuerpo los analizan como JSON y los combinan en el hash de parámetros.

Aquí está el controlador, junto con el método de filtro:

before do if request.request_method == "POST" body_parameters = request.body.read params.merge!(JSON.parse(body_parameters)) end end post ''/locations/new'' do content_type :json puts "params after post params method = #{params.inspect}" ... other code ... end

La salida que veo es básicamente que los parámetros en la acción del controlador en realidad están allí correctamente. Sin embargo, si comento fuera de la llamada los parámetros están vacíos.

El antes en sí se siente como un hack. Espero que esos parámetros lleguen en cualquier lugar ... Debo estar haciendo algo mal allí, pero no sé qué es.

Cualquier ayuda sería muy apreciada...


Tuvo un problema similar: la publicación de parámetros JSON de java al servicio sinatra

Encontré una mejor solución para lidiar con ella, agregando un middleware para hacer lo mismo por mí. Utilicé la gema del bastidor. Los siguientes son los cambios que hice en mi código:

EDITAR: use git para obtener la versión específica, donde soluciona el problema cuando el tipo de contenido es application/json;charset=UTF-8

Gemfile:

gem ''rack-contrib'', git: ''[email protected]:rack/rack-contrib'', ref: ''b7237381e412852435d87100a37add67b2cfbb63''

config.ru:

use Rack::PostBodyContentTypeParser

fuente: http://jaywiggins.com/2010/03/using-rack-middleware-to-parse-json/