I'm not sure if nested namespaces are actually supported as I don't see any specific mention of them in the docs. Anyhow in Sinatra 1.4.8 I could define an app like:
require 'sinatra'
require 'sinatra/contrib'
require 'json'
BOOKS = {
1 => {name: 'The Lord of the Rings'},
2 => {name: 'The Chronicles of Narnia'},
3 => {name: 'Harry Potter'},
}
namespace '/api' do
namespace '/v1' do
namespace '/books' do
get do
body JSON.dump(BOOKS)
end
end
end
end
cURLing the endpoint:
$ curl localhost:4567/api/v1/books
{"1":{"name":"The Lord of the Rings"},"2":{"name":"The Chronicles of Narnia"},"3":{"name":"Harry Potter"}}
Now if I define a similar app in Sinatra 2.0.0:
require 'sinatra'
require 'sinatra/contrib'
require 'json'
BOOKS = {
1 => {name: 'The Lord of the Rings'},
2 => {name: 'The Chronicles of Narnia'},
3 => {name: 'Harry Potter'},
}
namespace '/api' do
namespace '/v1' do
namespace '/books' do
get do
body JSON.dump(BOOKS)
end
end
end
end
And then cURL the same path:
$ curl localhost:4567/api/v1/books
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body { text-align:center;font-family:helvetica,arial;font-size:22px;
color:#888;margin:20px}
#c {margin:0 auto;width:500px;text-align:left}
</style>
</head>
<body>
<h2>Sinatra doesn鈥檛 know this ditty.</h2>
<img src='http://localhost:4567/__sinatra__/404.png'>
<div id="c">
Try this:
<pre>get '/api/v1/books' do
"Hello World"
end
</pre>
</div>
</body>
</html>
With this 2.0.0 Sintra app I decided to list all the GET paths:
Sinatra::Application.routes["GET"].each do |route|
puts route[0]
end
Which results in:
/api/v1/v1/books
If I cURL that path I get a successful result:
$ curl localhost:4567/api/v1/v1/books
{"1":{"name":"The Lord of the Rings"},"2":{"name":"The Chronicles of Narnia"},"3":{"name":"Harry Potter"}}
The repeated v1/v1 is not expected. Sinatra 1.4.8's /api/v1/books is the behaviour I would have expected.
Is this supposed to work? If there is a better way to define nested namespaces please let me know.
We are experiencing the same problem.
Sinatra 2 introduced Mustermann as a dependency for string matching, the errors are originating from that gem.
An weird behavior is that if the second level namespace is a param like /:version instead of /v1 in the example above, you would get:
lib/mustermann/ast/validation.rb:34:in `check_name': can't use the same capture name twice: "/{version}/{version}/books/?" (Mustermann::CompileError)
@mencargo I've seen that same error too when trying to setup params within namespace; however when I reported the issue I was trying to make it as simple as possible. Both scenarios used to work and now no longer do.
However, I don't see any documentation indicating that they were ever supported and I am just hoping we get some clarification on this issue. It's blocking my upgrade from 1.x to 2.x.
I wonder if this is similar to #1251 or affected in some way.
There is also _some_ coverage for nested namespaces here:
https://github.com/sinatra/sinatra/blob/69a7b8f23321f19c6de02212153f2821c16c25c7/sinatra-contrib/spec/namespace_spec.rb#L468-L478
/cc @mwpastore @namusyaka
I'm going to take a look at this issue in a few days.
@namusyaka 銇婇銇勮嚧銇椼伨銇欙紒 :pray:
@aren55555 @mencargo @zzak Could you confirm my pull request(#1322)?
Most helpful comment
@aren55555 @mencargo @zzak Could you confirm my pull request(#1322)?