Как создать сложный диспетчер URL - PullRequest
1 голос
/ 01 декабря 2011

Я пытаюсь разработать диспетчер 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 Ответ

1 голос
/ 01 декабря 2011

Я не думаю, что код, который вы показали, действительно работает :). Попробуйте, например:

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

и вы увидите, что отправлены неправильные ресурсы. Проблема в том, что вы ставите edit и delete без кавычек, поэтому они обрабатываются как переменные шаблона и будут соответствовать чему угодно (и будут привязаны к сопоставленному значению). И именно поэтому ваш первый вариант не сработал - эти два шаблона одинаковы, вплоть до переименования переменных (редактировать / удалять). То, что вы хотите (я думаю):

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 типа: Uri.relative, которая имеет больше полей, чем просто path и query. ... означает, что в записи может быть больше полей, но мы не заботимся о них (без точек в записях ожидаются только явно упомянутые поля).

...