С маршрутами Синатры, как может быть как обязательный именованный параметр, так и необязательный именованный параметр в одной и той же части маршрута.
Опциональный параметр маршрута отлично работает здесь
get '/widgets.?:format?'
Но попробуйте объединить требуемый именованный параметр, и все обернется.
get '/widgets/:id.?:format?'
Запросы для /widgets/abc.json передают весь abc.json в качестве параметра id.
Синатраскомпилированное регулярное выражение:
/^\/widgets\/([^\/?#]+)(?:\.|%2E)?([^\/?#]+)?$/