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
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.
If you want to return a HTTP 200 response with JSON and set HTTP headers in Suave, then you can use the Writers.setHeader
function:
Writers.setHeader "Access-Control-Allow-Credentials" "true" >=>
Writers.setHeader "Access-Control-Allow-Headers:Content-Type" "Accept" >=>
Writers.setHeader "Access-Control-Allow-Methods" "GET, POST, PUT, DELETE, OPTIONS" >=>
Writers.setHeader "Access-Control-Allow-Origin" "" >=>
Successful.OK (movies |> Json.serialize |> Json.format)
The whole thing is an expression that constructs a WebPart
which you can then compose with other web parts using the functions provided by Suave. So if you wanted to pattern match before setting the headers, you'd use something like:
let php = request (fun r ->
match r.queryParam "playerName" with
| Choice1Of2 name ->
Writers.setHeader "Access-Control-Allow-Credentials" "true" >=>
Writers.setHeader "Access-Control-Allow-Headers:Content-Type" "Accept" >=>
Writers.setHeader
"Access-Control-Allow-Methods" "GET, POST, PUT, DELETE, OPTIONS" >=>
Writers.setHeader "Access-Control-Allow-Origin" "" >=>
Successful.OK (movies |> Json.serialize |> Json.format)
| Choice2Of2 msg -> BAD_REQUEST msg)
As you are setting the CORS headers, this snippet might also help.
来源:https://stackoverflow.com/questions/42013940/how-to-set-a-json-response-in-suave-webpart