Как создать сложный диспетчер URL
Я пытаюсь разработать диспетчер URL для выполнения различных действий в зависимости от URL. Например:
- http://localhost:8080/ -> перейти на домашнюю страницу
- http://localhost:8080/edit?id=2 -> перейти на страницу редактирования
- http://localhost:8080/delete?id=4 -> перейти на страницу удаления
На данный момент я получил следующий код, который работает:
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
, ...
означает, что в записи может быть больше полей, но мы не заботимся о них (без точек записи могли бы иметь только явно упомянутые поля).