Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow URI templates in paths #10

Closed
dselivanov opened this issue Jan 19, 2018 · 9 comments
Closed

Allow URI templates in paths #10

dselivanov opened this issue Jan 19, 2018 · 9 comments
Milestone

Comments

@dselivanov
Copy link
Collaborator

dselivanov commented Jan 19, 2018

RFC6570 and test suite https://github.com/uri-templates/uritemplate-test/tree/8014d2561706bfec7fd27a7465ff3f957381427c

@dselivanov dselivanov added this to the Public release milestone Jan 21, 2018
@dselivanov dselivanov changed the title Allow path in add_route() be a regex Allow URI templates in add_route() Feb 7, 2018
@dselivanov dselivanov changed the title Allow URI templates in add_route() Allow URI templates in paths Feb 7, 2018
@dselivanov dselivanov removed this from the Public release milestone Feb 7, 2018
@artemklevtsov
Copy link
Collaborator

При добавлении роута чекаем наличие переменных в пути. Если переменные есть, ставим отметку о том, что передан шаблон пути с переменными и разбираем эти переменные.

Пример кода для извлечения переменных:

  if(grepl("/\\{|\\}/", path)) {
    splitted <- strsplit(path, "/", fixed = TRUE)[[1L]][-1L]
    pos <- which(startsWith(splitted, "{") & endsWith(splitted, "}"))
    vars <- substr(splitted[pos], 2L, nchar(splitted[pos]) - 1L)
    private$handlers[[path]][[vars]] <- list(name = vars, pos = pos)
  }

Его предполагается вставить вот сюда.

По поводу матчинга путей при поиске подходящего обработчика. После проверки точного совпадения можно сплитнуть путь и сопоставить его с имеющимися, причём при сопоставлении учесть длину вектора и исключить ранее извлечённые переменные. Текущий вариант со startsWith можно оставить для роутов без шаблонов.

@artemklevtsov
Copy link
Collaborator

Нашёл реализацию похожего функционала в пакете routr: https://github.com/thomasp85/routr/blob/master/R/route.R#L273

@artemklevtsov
Copy link
Collaborator

@artemklevtsov
Copy link
Collaborator

artemklevtsov commented Jun 28, 2019

First try to make structure for the paths: https://gist.github.com/artemklevtsov/a158e6cac89dc43c454552d8a83249fd
This code can detect, exrtact and parse variables from the URL templates. Also variables types supported (as native R classes).
We can separate exact, partial and regex paths and match its with same order.
We need to do some refactoring to use this structure.

@artemklevtsov
Copy link
Collaborator

artemklevtsov commented Jul 1, 2019

Предложенный выше объект R6 предлагается использовать в add_route. При этом организацию обработчиков предлагаю изменить следующим образом:

  • вместо схемы: handlers$path[[method]] использовать handlers[[method]]$path, что должно сократить область поиска.
  • При добавлении новых точек досутпа в handlers[[method]] сначала добавлять точки с методом exact, а в самый конец с методовмregex. partial между ними.

@artemklevtsov
Copy link
Collaborator

artemklevtsov commented Jul 1, 2019

Если будет просадка по производительности, то для точного соответствия можно исопльзовать fastmatch (нет зависимостей), а для regex ore (нет зависимостей. бенч) или stringi.

@artemklevtsov
Copy link
Collaborator

artemklevtsov commented Jul 3, 2019

Думается надо запилить отдельный R6Class для хранения и обработки путей, которые будет инициализирован для каждого метода в handlers[[method]]. Все пути можно разделить на 3 группы:

  • Точный (exact). Для этих путей мы ищем точное соответствие с помощью == + which. Ограничение: не должен оканчиваться на /.
  • Частичный (partial). Для этих путей ищем частичное соответствие с помощью startsWith или аналогов (желательна параллельная проверка множества паттернов). Ограничение: должен оканчиваться на /? Также этот вариант может быть представлен как /prefix/.*.
  • Шаблон (regex). Для этих путей ищем с помощью stri_detect_regex_first или аналогов (желательна параллельная проверка множества паттернов). Переменные задаются в фигурных скобках ({var}). После разбора переменных формируется data.frame с названием переменной, типом данных (указывается через : и заменятеся на character в случае отсутствия) и позиция в пути от корня.
    При совпадении префикса у частичного пути и регулярки, сначала необъодимо проеврять регулярки, т.к. префикс будет более общим случаем, ибо может быть записано как /prefix/.*.
    Класс должен содержать метод add_path и match_path.
    Для сведения поиска по регуляркам к минимуму предалаегтся сначала искать частичное соответствие. Для примера в пути /weather/{city} сначала проверить startsWith(path, "/weather/") и в случае успеха stri_detect_regex_first(path, "/weather/[^\]/?$")
    Замечание: пакет re2r можео принимать несколько регулярок и гоняет их с помощью RcppParallel.
    Вопросы:
  • На что заменять названия переменных при генерации регулярных выражений. Текущий вариант - [^/]+.
  • Могут ли совпадать пути в exact и partial или при добавление бросаем ошибку? Например, /status и /status/. В unix-like ОС не могут существовать одновременно файл и директория с одним названием.
  • Могут ли совпадать префиксы путей для partial и regex или при добавлении бросаем ошибку? Например: /weather/ и /weather/{city}.

@artemklevtsov
Copy link
Collaborator

artemklevtsov commented Jul 4, 2019

Могут ли совпадать префиксы путей для partial и regex или при добавлении бросаем ошибку? Например: /weather/ и /weather/{city}.

Думаю, ответ должен быть такой. Префикс /weather/ должен интерпретироваться как /weather/.+$ и является более общим случаем /weather/[^/]+/?$. Поэтому вариант /weather/[^/]+/?$ должен проверяться в первую очередь.

@artemklevtsov
Copy link
Collaborator

artemklevtsov commented Jul 21, 2019

#34 should fix it.
Now merged to dev.

@dselivanov dselivanov added this to the 0.2 milestone Jul 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants