¿Cómo puedo extraer un "extractEntityFromPostedJson" en Yesod?

Después de un poco de prueba y error, logré crear la siguiente función en Yesod para tomar un objeto de un JSON POST, crear un EventFolder entidad y guárdelo en la base de datos.

postAddEventFolderR :: Handler RepJson
postAddEventFolderR = do
    r <- waiRequest 
    v <- liftIO . runResourceT $ requestBody r $$ sinkParser json
    let v1 :: EventFolder
        v1 = case fromJSON v of
                 Success a -> a
                 Error s   -> error s
    runDB $ insert $ v1
    return $ RepJson $ toContent $ show v1

La función de prueba parece curl -H "Content-Type: application/json" -X POST -d '{"name":"test_folder"}' http://localhost:5000/AddEventFolder.

La pregunta es, bueno, primero, ¿hay una forma más concisa de escribir esta función? Parece bastante prolijo. Y segundo, ¿cómo podría extraer una función que genéricamente crea un objeto del JSON? Así que me gustaría terminar con algo como

postAddEventFolderR = do
    v1 = extractEntityFromJsonPost (whatever params) :: EventFolder
    runDB $ insert $ v1
    return $ RepJson $ toContent $ show v1

Tenga en cuenta que soy completamente nuevo en Haskell.

preguntado el 22 de mayo de 12 a las 15:05

1 Respuestas

Creo que la función que estás buscando es parseJsonBody_. Además, en lugar de usar toContent y show, creo que te gustaría usar jsonToRepJson. Entonces, en conjunto, probablemente puedas expresar tu código como:

postAddEventFolderR = do
    v <- parseJsonBody_
    runDB $ insert (v :: EventFolder)
    jsonToRepJson v

Aunque no estoy del todo seguro de por qué está respondiendo con los datos que el cliente acaba de enviar.

contestado el 22 de mayo de 12 a las 16:05

Muchas gracias. Si no le importa, también vincularé uno de sus repositorios aquí para ver un ejemplo más grande. github.com/snoyberg/yesod-js/blob/master/samples/todo.lhs - langosta

@ el problema de la respuesta: se acostumbra hacer una de estas tres cosas al responder a un POST: devolver la entrada publicada con las modificaciones realizadas, devolver algún tipo de mensaje de "estado correcto" o enviar una respuesta de redireccionamiento. @lobsterism está aquí optando por la alternativa 1; si ENVÍAS a /folder/new con name=test_folder, y la carpeta ya existe, puede responder con {"name":"test_folder (1)"} para indicar que el recurso /folder/test_folder (1) fue creado. Obviamente, el código para eso no está implementado aquí. - dflemstr

En realidad, la respuesta fue solo un marcador de posición. Aún queda mucho por hacer. . . - langosta

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.