如何在F#Saturn Framework中获取查询参数?

时间:2018-07-14 15:06:27

标签: f# f#-giraffe saturn-framework

说我们有这个Web服务器来处理请求:

let webApp = scope {
    get  "/api/zoo/animals/"    (getAllAnimals())
    getf "/api/zoo/animals/%s"  getAnimalInfo
}

此语法在docs中进行了描述,并在example中进行了演示。

现在,如果我想在url查询中添加一个参数,例如过滤结果?

http://localhost:8080/api/zoo/animals?type=mammals

这不会做任何事情:

getf "/api/zoo/animals?type=%s" getAnimalsByType

2 个答案:

答案 0 :(得分:3)

一种解决方法是使用上下文的功能GetQueryStringValue。它返回Result,一个结构DU。

所以您保留了初始签名(只需删除尾部斜杠):

get "/api/zoo/animals" (getAnimals())

你有

let getAnimals() : HttpHandler =
    fun _ ctx -> task { 
        let animalTypeFromQuery = ctx.GetQueryStringValue "type"
        let animalType =
            match animalTypeFromQuery with
            | Ok t    -> Some t
            | Error _ -> None
        ...
    }

我不知道这是否是官方惯例,我在某些F#github存储库中发现了这种惯例。

答案 1 :(得分:3)

在此处查看示例:

https://github.com/giraffe-fsharp/Giraffe/blob/master/DOCUMENTATION.md#query-strings

它显示了如何绑定查询字符串中的数据,因此您不必使用GetQueryStringValue

对于您而言,我认为类似的方法可能有用。

[<CLIMutable>]
type AnimalType =
    { type : string }

let animal (next : HttpFunc) (ctx : HttpContext) =
    // Binds the query string to a Car object
    let animal = ctx.BindQueryString<AnimalType>()

    // Sends the object back to the client
    Successful.OK animal next ctx

let web_app  =

    router {    
        pipe_through (pipeline { set_header "x-pipeline-type" "Api" })
        post "/api/animal" animal
    }