Search code examples
phpjsonhttpf#suave

How to set a Json response in suave webpart


i'm begining with Suave and F#. I'm trying to pass a json serialized object in my webpart to get it in my response.

In php i have this

<?php
header('Access-Control-Allow-Credentials:true');
header('Access-Control-Allow-Headers:Content-Type, Accept');
header('Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Origin:*');
?>
{
 "player1Key":"hdegftzj25",
 "gameKey":"aegfhzkfszl74852"
}

and with this i get my json object, then i tried to do the same with Suave and Newtonsoft.Json

type gameCreate= {
    player1Key : string
    gameKey: string
}

let create= { player1Key = "BadBoys2"; gameKey = "zLUGgtrht4456" }

let json = Newtonsoft.Json.JsonConvert.SerializeObject(create)

//OK (acc |> Json.serialize |> Json.format )
let php =
request (fun r ->
    match r.queryParam "playerName" with
    | Choice1Of2 name ->  OK (movies |> Json.serialize(json) |> Json.format(json))
                        //|>  Response.response(Json.toJson(info))
                        //|>  OK
    | Choice2Of2 msg -> BAD_REQUEST msg)

let webPart = 
choose [
path "/" >=> (OK "Home")
path "/elm/api/create.php" >=> php
]

startWebServer defaultConfig webPart

So i can create and serialize a json object but i don't know how to pass it as http response in my web part and with the above code i keep on getting error on my expressions type in my let php


Solution

  • Looks like you've pulled in a few Json serialization libraries too many - you seem to mix bits of Json.NET and Chiron (which is used in the tutorial), to no great effect...

    Let's take a step back. Suave comes with its own Json serialization module, so you can get something working just by using that. Here's how it would look:

    let php =
        request (fun r ->
            match r.queryParam "playerName" with
            | Choice1Of2 name ->  
                let json : string = 
                    create
                    // this comes from Suave.Json, gives you a byte array
                    |> Json.toJson           
                    // converts the byte array into a string
                    |> System.Text.Encoding.UTF8.GetString
                OK json
            | Choice2Of2 msg -> BAD_REQUEST msg)
    

    Now, if you want, you can replace the Json.toJson call with either the Newtonsoft Json.NET or Chiron implementation (but hopefully not a mix of the two). As long as the types align, you should be fine.

    For Chiron in particular, you're missing the ToJson static member on the type you want to serialize (this is something that your tutorial does mention). Json.NET has a generic serialize function that produces json corresponding to the record schema, so it's a bit easier to use out of the box, but also requires more work to customize the output if needed.