Не знаю, почему я не сделал этого ещё год назад, но сейчас залез в исходный код, удалил несколько мертворождённых идей и добавил даже, как мне кажется, лучшую возможность: теперь можно при создании маршрута указывать пользовательскую функцию для парсинга переменной шаблона. Например:
CL-USER>(defparameter *map* (make-instance 'routes:mapper))В данном примере используется стандартная функция #'parse-integer, что позволяет убедиться в том, что параметр id содержит только цифры, а кроме того - в случае успешного сопоставления url шаблону в параметре :id будет не строка, а целое число.
CL-USER>(routes:connect *map* (routes:make-route "/foo/:id" (list :id #'parse-integer)))
CL-USER>(routes:match *map* "/foo/1")
(#<ROUTES:ROUTE {...}> (:ID . 1))
CL-USER>(routes:match *map* "/foo/hello")
NIL
Подобным образом можно использовать любую функцию, которая должна принимать строку, а возвращать объект, который будет сопоставлен переменной шаблона. Если строка не соответствует требованиям, то эта функция должна вернуть nil или сигнализировать об ошибке (эта возможность добавлена для возможности непосредственного использования #'parse-integer)
Соответственно, тут же немного доработал RESTAS, например теперь возможно задавать маршруты следующим образом:
(define-route myroute ("/foo/:id" :parse-vars (list :id #'parse-integer))Для использования этой новой возможности необходимо использовать git-версии cl-routes и RESTAS. Впрочем, новые релизы я думаю будут довольно скоро.
...)
Когда же я найду время попробовать всё это?...
ОтветитьУдалить@andy128k
ОтветитьУдалитьЭ... Ты хочешь у меня это узнать? ;)
почему не?
ОтветитьУдалитьdefine-route myroute ("/foo/:id" :parse-vars (:id #'parse-integer))
зачем лишний вызов list ?
@kmmbvnr
ОтветитьУдалитьЧто бы можно было один plist, определённый в другом месте, использовать для всех маршрутов. В этом есть смысл, если использовать стандартные имена переменных в маршрутах.