如何使用Suave捕获动态子路径(例如“ / COMPANY / rest ...”)并嵌套路径?

时间:2019-02-18 22:37:34

标签: f# routes suave

我有几条必须按“公司”分组的路由,以及一些对所有用户都有效的路由:

/login
/logout
/demo1/customers
/demo1/products

因此,我尝试使用suave:

let doReqScan action =
     warbler (fun r ->
        LOG.Debug("ROUTE: {route}", r.request.url)
        match r.request |> getCompany with
        | Some(x) ->
            let isAuth, validDb = isValidDb(x)

            if validDb then
                if isAuth then
                    action(r.request) |> _DoSet
                else
                    jSonNoAuth
            else    
                never
        | _ -> never
    )

let doReq(route:string, action) =
    path route >=> doReqScan action  

let appCompany company =
    choose [      
      path "/ws" >=> handShake ws
      GET >=>  choose
        [
          doReq("/customers", (fun r -> queryCustomers(r)))
          pathScan "/customers/%d" (fun the_id -> doReqScan (fun r -> queryCustomer(r, the_id)))
        ]
     ]
let app =
  choose
    [ allow_cors
      pathScan "/%s" (fun company ->
       choose
            [
                appCompany company
                GET >=>  choose
                  [
                    _doReq( "/config", (fun r -> config(r)) )
                  ]
                POST >=> choose
                  [
                    _doReq( "/login", (fun r -> login(r)))
                    _doReq( "/logout", (fun r -> logout(r)))
                  ]
            ]
        )
      GET >=> Files.browseHome
      jSonNotFound
    ]

但是,pathScan捕获所有URL“ / demo1 / customers”,而不是仅捕获“ / demo1”。

2 个答案:

答案 0 :(得分:1)

如果我正确理解:

  • 所有常用网址的格式为:/something
  • 所有公司网址的格式为:/companyName/something

然后您可以尝试以下操作:

let appCompany company =
    let com x = "/" + company + x
    choose [      
        path (com "/ws") >=> handShake ws
        GET >=> choose [
            doReq(com "/customers", (fun r -> queryCustomers(r)))
            pathScan "/%s/customers/%d" (fun _ the_id -> doReqScan (fun r -> queryCustomer(r, the_id)))
        ]
    ]

let app =
    choose [
        allow_cors
        GET >=> choose [
                    _doReq( "/config", (fun r -> config(r)) )
                ]
        POST >=> choose [
                    _doReq( "/login", (fun r -> login(r)))
                    _doReq( "/logout", (fun r -> logout(r)))
                 ]
        pathScan "/%s/%s" (fun company _ -> appCompany company)
        GET >=> Files.browseHome
        jSonNotFound
    ]

答案 1 :(得分:1)

查看长颈鹿文档中提出的内容(类似于Suave in spirit)。他们使用一次所有部分名为subroutef

的pathScan

所以它就像:

pathScan "/%s/customers" queryCustomers
pathScan "/%s/products" queryProducts
...