如何在 suave webpart 中设置 Json 响应
How to set a Json response in suave webpart
我从 Suave 和 F# 开始。
我正在尝试在我的 Web 部件中传递一个 json 序列化对象以在我的响应中获取它。
在php我有这个
<?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"
}
然后我得到了我的 json 对象,然后我尝试对 Suave 和 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
所以我可以创建并序列化一个 json 对象,但我不知道如何在我的 Web 部件中将它作为 http 响应传递,并且使用上面的代码我的表达式类型不断出错我让 php
如果您想 return 使用 JSON 的 HTTP 200 响应并在 Suave 中设置 HTTP headers,那么您可以使用 Writers.setHeader
函数:
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)
整个事情是一个构造 WebPart
的表达式,然后您可以使用 Suave 提供的功能将其与其他 Web 部件组合。所以如果你想在设置 headers 之前进行模式匹配,你可以使用类似的东西:
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)
在设置 CORS 时 headers、this snippet might also help。
看起来你引入了一些 Json 序列化库太多 - 你似乎混合了 Json.NET 和 Chiron(在教程中使用)的位,但效果不佳...
让我们退一步。 Suave 带有它自己的 Json 序列化模块,所以你可以通过使用它来获得一些东西。它的外观如下:
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)
现在,如果需要,您可以将 Json.toJson
调用替换为 Newtonsoft Json.NET 或 Chiron 实现(但希望不要混合使用两者)。只要类型对齐,就应该没问题。
特别是对于 Chiron,您缺少要序列化的类型的 ToJson
静态成员(这是您的教程确实提到的内容)。 Json.NET 有一个生成 json 对应于记录模式的通用序列化函数,因此开箱即用更容易一些,但如果需要,还需要做更多工作来自定义输出。
我从 Suave 和 F# 开始。 我正在尝试在我的 Web 部件中传递一个 json 序列化对象以在我的响应中获取它。
在php我有这个
<?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"
}
然后我得到了我的 json 对象,然后我尝试对 Suave 和 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
所以我可以创建并序列化一个 json 对象,但我不知道如何在我的 Web 部件中将它作为 http 响应传递,并且使用上面的代码我的表达式类型不断出错我让 php
如果您想 return 使用 JSON 的 HTTP 200 响应并在 Suave 中设置 HTTP headers,那么您可以使用 Writers.setHeader
函数:
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)
整个事情是一个构造 WebPart
的表达式,然后您可以使用 Suave 提供的功能将其与其他 Web 部件组合。所以如果你想在设置 headers 之前进行模式匹配,你可以使用类似的东西:
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)
在设置 CORS 时 headers、this snippet might also help。
看起来你引入了一些 Json 序列化库太多 - 你似乎混合了 Json.NET 和 Chiron(在教程中使用)的位,但效果不佳...
让我们退一步。 Suave 带有它自己的 Json 序列化模块,所以你可以通过使用它来获得一些东西。它的外观如下:
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)
现在,如果需要,您可以将 Json.toJson
调用替换为 Newtonsoft Json.NET 或 Chiron 实现(但希望不要混合使用两者)。只要类型对齐,就应该没问题。
特别是对于 Chiron,您缺少要序列化的类型的 ToJson
静态成员(这是您的教程确实提到的内容)。 Json.NET 有一个生成 json 对应于记录模式的通用序列化函数,因此开箱即用更容易一些,但如果需要,还需要做更多工作来自定义输出。