Roteamento
O que é roteamento
No Sinatra, roteamento é como seu aplicativo responde às solicitações, pelo caminho da solicitação (por exemplo, /welcome
) e pelo verbo HTTP
usado (por exemplo, GET
ou POST
). A maneira como uma solicitação é escrita é a seguinte:
<http-verb> <path> do
<code block to execute when this route is requested>
end
Aqui está um exemplo que responde a solicitações GET
para o caminho /hello
retornando uma página que diz “Hi, whats up”:
get "/hello" do
return "Hi, whats up"
end
O Sinatra só responde às rotas que você definir. Se você não definir uma rota, o Sinatra retornará uma página de erro 404 Page Not Found
.
O Sinatra responde às rotas na ordem em que são definidas. Se você tiver várias rotas que podem corresponder a uma determinada solicitação (consulte “Correspondência de caminho baseada em Regexp”), a primeira rota que se encaixa na solicitação é retornada.
OBSERVAÇÃO: Sinatra trata rotas com e sem barra (/
) como 2 rotas diferentes e distintas. Ou seja, get '/hello'
e get '/hello/'
por padrão correspondem a diferentes blocos de código. Se você quiser ignorar a barra à direita e tratar ambas as rotas como a mesma, você pode adicionar ?
após a barra para torná-la opcional, assim: get '/hello/?'
. Isso usa a capacidade do Sinatra de usar expressões regulares para correspondência de rotas (mais sobre isso abaixo).
Verbos de roteamento Sinatra disponíveis
Existem vários verbos de roteamento disponíveis no Sinatra, eles correspondem diretamente aos verbos http
get '/' do
.. get some data, a view, json, etc ..
end
post '/' do
.. create a resource ..
end
put '/' do
.. replace a resource ..
end
patch '/' do
.. change a resource ..
end
delete '/' do
.. delete something ..
end
options '/' do
.. appease something ..
end
link '/' do
.. affiliate something ..
end
unlink '/' do
.. separate something ..
end
Correspondência de caminho baseada em Regexp
Ao combinar o caminho de uma rota, você pode fazer isso explicitamente, correspondendo apenas a um caminho, assim:
get "/hello" do
return "Hello!"
end
Você também pode usar uma expressão regular para corresponder a rotas complexas. Qualquer rota que corresponda à expressão regular executará esse bloco de código. Se várias rotas puderem corresponder à solicitação, a primeira rota correspondente será executada.
Aqui está um exemplo típico de uma rota que corresponde a caminhos que incluem /user/
seguido por um ou mais dígitos (presumivelmente, IDs de usuário), ou seja, GET /user/1
:
get /\/user\/\d+/ do
"Hello, user!"
end
O exemplo acima corresponde a /user/1
, mas também corresponde a /delete/user/1
e /user/1/delete/now
, já que nossa expressão regular não é muito restritiva e permite uma correspondência parcial com qualquer parte do caminho.
Podemos ser mais explícitos com o regexp e dizer a ele para corresponder exatamente à rota, usando as diretivas \A
e \z
para ancorar a correspondência no início e no final do caminho:
get /\A\/user\/\d+\z/ do
"Hello, user!"
end
Esta rota não corresponderá a /delete/user/1
ou /user/1/delete/now
devido à ancoragem de correspondência.
Ignorando à direita /
Nossa rota de exemplo acima também não corresponderá a /user/1/
(com barra à direita). Se você quiser ignorar a barra final no final da rota, ajuste o regexp para tornar a barra opcional (observe o \/?
no final):
get /\A\/user\/\d+\/?\z/ do
"Hello, user! You may have navigated to /user/<ID> or /user/<ID>/ to get here."
end
Capturando correspondências de rota
Até agora, combinamos com rotas regexp, mas e se quisermos usar os valores correspondentes em nosso bloco de código? Dando continuidade ao nosso exemplo, como sabemos qual é o ID do usuário quando a rota é executada?
Podemos capturar a parte desejada do caminho e usar a variável param[:captures]
do Sinatra para trabalhar com os dados dentro da rota:
get /\A\/user\/(\d+)\/?\z/ do
"Hello, user! Your ID is #{params['captures'].first}!"
end
Parâmetros da Rota Sinatra
Claro que você pode passar dados para rotas Sinatra, para aceitar dados em suas rotas você pode adicionar parâmetros de rota. Você pode então acessar um hash de parâmetros:
get '/hello/:name' do
# matches "GET /hello/foo" and "GET /hello/bar"
# params['name'] is 'foo' or 'bar'
"Hello #{params['name']}!"
end
Você também pode atribuir parâmetros diretamente a variáveis como costumamos fazer em hashes Ruby:
get '/hello/:name' do |n|
# matches "GET /hello/foo" and "GET /hello/bar"
# params['name'] is 'foo' or 'bar'
# n stores params['name']
"Hello #{n}!"
end
Você também pode adicionar parâmetros curinga sem nomes específicos usando asteriscos. Eles podem ser acessados usando params[‘splat’]:
get '/say/*/to/*' do
# matches /say/hello/to/world
params['splat'] # => ["hello", "world"]
end