代码之家  ›  专栏  ›  技术社区  ›  LA.27

嵌套Suave Web部件

  •  2
  • LA.27  · 技术社区  · 7 年前

    我试图实现的是实现一个简单的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
    

    当我这样定义Web部件时:

    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
        ]
    ]
    

    1 回复  |  直到 7 年前
        1
  •  4
  •   JosephStevens    7 年前

    是的,所以访问以前的请求有点反文雅;)我们希望事情能够独立发生,不管刚刚发生了什么。因此,也许解决这一问题的更好方法是简单地将价格附加到路径的末端?

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