【问题标题】:Nesting Suave WebPart嵌套 Suave WebPart
【发布时间】:2017-07-19 12:12:42
【问题描述】:

我第一次玩 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
]

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

// 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 时,我的推理可能存在差距。我认为以这种方式嵌套价格端点清楚地表明价格被视为一种工具的属性(如果我错了,请随时纠正我)。

【问题讨论】:

  • 这不是它的工作方式。您必须放弃“当前请求”的概念。 Suave中没有这样的东西。都是函数组合。

标签: rest f# suave


【解决方案1】:

是的,所以访问先前的请求是一种反文雅;)我们希望事情能够独立发生,而不管刚刚发生了什么。那么,解决这个问题的一种更好的思考方式可能是简单地将价格附加到路径的末尾?

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

【讨论】:

  • 与我当前的解决方案完全一样,对吧(即我发布的那个有效)?另外-感谢您对被认为是“反文雅”的解释。这是我想听到的。
  • 我认为他没有尝试访问先前的请求。更像是嵌套 pathScan 链的前一部分。这是一个不止一次出现的功能请求(人们要求某种subPath 组合器),但现在我找不到其他功能请求的提交位置。如果我找到它们,我会链接它们。但目前,Suave 不提供该功能。
猜你喜欢
  • 2023-03-11
  • 2011-04-09
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多