如何创建复杂的URL调度程序

时间:2011-12-01 09:27:21

标签: opa

我正在尝试开发一个URL调度程序,以根据URL执行不同的操作。例如:

至于现在,我得到了以下有效的代码:

dispatch(uri) =
match uri with
  | {path= [edit] query=[("id", parameter)] ...} -> Customer.edit(parameter)
  | {path= [delete] query=[("sid", parameter)] ...} -> Customer.delete(parameter)
  | {~path ...} -> start()

server = Server.simple_dispatch(dispatch)

然而,在我的第一次尝试中,我有:

  | {path= [edit] query=["id", parameter] ...} -> Customer.edit(parameter)
  | {path= [delete] query=[("id", parameter)] ...} -> Customer.delete(parameter)

但是由于两行中都有“id”,编译器会抛出错误,显然第一行是“覆盖”第二行。我的问题是:

  • 如何为这两行保留相同的参数名称“id”而不会出现错误?
  • 如何处理多个不同类型的参数?例如localhost:8080 / edit?id = 2& ask = true& showImage = 0
  • “......”的模式是什么?

提前致谢

1 个答案:

答案 0 :(得分:1)

我不认为你展示的代码真的有用:)。试试例如:

/delete?id="xxx"
/edit?sid="xxx"

您将看到调度错误的资源。问题是您将editdelete放在没有引号的情况下,因此将它们视为模式变量并将匹配任何内容(并绑定到匹配的值)。而这正是您的第一个变体不起作用的原因 - 这两个模式是相同的变量重命名(编辑/删除)。你想要的(我认为)是:

dispatch =
| {path = ["edit"] query=[("id", parameter)] ...} -> Customer.edit(parameter)
| {path = ["delete"] query=[("id", parameter)] ...} -> Customer.delete(parameter)
| {~path ...} -> start()

如何拥有多个参数?

只需将您的模式匹配(第一行)扩展为:

| {path = ["edit"] query=[("id", id), ("ask", ask), ("showImage", showImage)] ...} -> Customer.edit(id, ask, showImage)

但是这种匹配是危险的,因为如果只有那些查询参数并且按照这个顺序,只会工作。如果你不能确定更好的做法:

| {path = ["edit"] ~query ...} ->
    id = List.assoc("id", query) ? ""
    ask = List.assoc("ask", query) ? ""
   showImage = List.assoc("showImage", query) ? ""
    Customer.edit(id, ask, showImage)

现在订单无关紧要,如果缺少参数,将使用默认值(?之后)。

“......”的模式是什么?

您要匹配uri类型的path变量:Uri.relative,其中的字段数不仅仅是query...。 {{1}}表示记录中可能有更多字段,但我们并不关心它们(没有点,记录预计只会明确提到字段)。