Как создать сложный диспетчер URL

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

Решение

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

/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, ... означает, что в записи может быть больше полей, но мы не заботимся о них (без точек записи могли бы иметь только явно упомянутые поля).

Другие вопросы по тегам