rest - 嵌套 Suave Web 部件

标签 rest f# suave

我第一次玩 Suave,显然有些东西我不明白。 我想要实现的是实现一个简单的 Rest API:

  • 用户可以获得有关金融工具的信息
  • 此外,每种乐器都有价格表

为了简单起见,现在我只关注 GET 方法。

我的非常基本代码在这里:

[<AutoOpen>]
module RestFul =    

    let JSON v =     
        let jsonSerializerSettings = new JsonSerializerSettings()
        jsonSerializerSettings.ContractResolver <- new CamelCasePropertyNamesContractResolver()

        JsonConvert.SerializeObject(v, jsonSerializerSettings)
        |> OK 
        >=> Writers.setMimeType "application/json; charset=utf-8"

    let fromJson<'a> json =
        JsonConvert.DeserializeObject(json, typeof<'a>) :?> 'a    

    let getResourceFromReq<'a> (req : HttpRequest) = 
        let getString rawForm = System.Text.Encoding.UTF8.GetString(rawForm)
        req.rawForm |> getString |> fromJson<'a>

    type RestResource<'a> = {
        GetById : int -> 'a option
        GetPricesById : int -> 'a option
    }

    let rest resource =

        let handleResource requestError = function
            | Some r -> r |> JSON
            | _ -> requestError

        let getResourceById = 
            resource.GetById >> handleResource (NOT_FOUND "Resource not found")

        let getPricesById = 
            resource.GetPricesById >> handleResource (NOT_FOUND "Resource not found")

        choose [
            GET >=> pathScan "/instrument/%d" getResourceById
            GET >=> pathScan "/instrument/%d/prices" getPricesById
        ]


module Main =
    [<EntryPoint>]
    let main argv = 

        let webPart = rest {
                GetById = fun i -> Some i // placeholder
                GetPricesById = fun i -> Some i // placeholder, it'll be a list eventually
            }

        startWebServer defaultConfig webPart
        0

当我以这种方式定义 WebPart 时:

choose [
    GET >=> pathScan "/instrument/%d" getResourceById // Returns the instrument static data
    GET >=> pathScan "/instrument/%d/prices" getPricesById // Returns price list for the instrument
]

然后一切正常。我想知道是否有办法嵌套网络部件,例如像这样:

// My idea about the code - doesn't compile
choose [
    pathScan "/instrument/%d" getResourceById >=> choose [
        GET // Returns the instrument static data
        GET >=> path "/prices" >=> (somehow refer to the previous id and get prices)  // Returns price list for the instrument
    ]
]

此外 - 当我学习 RestAPI 时,我的推理可能存在差距。我认为以这种方式嵌套价格端点可以清楚地表明价格被视为工具的属性(如果我错了,请随时纠正我)。

最佳答案

是的,所以访问之前的请求有点反文雅;)我们希望无论刚刚发生了什么,事情都能够独立发生。那么也许解决这个问题的更好的思考方法就是简单地将价格附加到路径的末尾?

choose [
    GET >=> pathScan "/instrument/%d" getResourceById 
    GET >=> pathScan "/instrument/%d/prices" getPricesById
]

关于rest - 嵌套 Suave Web 部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45190215/

相关文章:

f# - 模式匹配多个变量

json - F# 将 JSON 反序列化为字符串或节点

f# - 从 Suave 请求中聚合信息

f# - 是否可以使用 webpart GET 值创建类实例

c# - 现在 WebServiceHost2Factory 已死,我如何从 WCF 休息服务返回错误文本?

java - 由于在 REST 中使用 HATEOAS 而导致循环依赖

F# 累积随机数序列

f# - 在 Suave 中允许多个带有 CORS 的 header

php - 为什么我对 PHP 脚本/WP REST API 的并发 AJAX 请求如此慢?

java - 来自 netbeans 数据库的 Restful java Web 服务