Params

Now, sometimes the request path contains dynamic data.

For example, the path of the URL https://rubygems.org/gems/rack is /gems/rack. The path of the details page for the gem Sinatra on RubyGems.org is /gems/sinatra, the path for Middleman is /gems/middleman, and so on.

Obviously we don’t want to hardcode (“write out literally”) all these names in our application code: We don’t want to change our code for each and every new gem that is added: At the time of this writing RubyGems.org has 122,037. Instead we want to be able to express “a path that starts with /gems followed by another, second segment”.

In Sinatra we can do this by specifying a pattern as a path. Sinatra will then match the pattern against the path, and see if it applies.

Let’s try that out.

Add the following route (request handler) to your program, at the end of the file:

get "/monstas/:name" do
  "Hello #{params["name"]}!"
end

Restart your Sinatra application, and point your browser to http://localhost:4567/monstas/monstas.

How does this work?

params is a hash that Sinatra makes available for you in your route blocks, and it will automatically include relevant data from the request.

In our case our route specifies a path that is a pattern: the last part of the path starts with a colon :. This tells Sinatra that we’d like to accept any string here, and that we’d like to call this string name.

Sinatra therefore adds the key "name" to the params hash, and sets the given string from the path (i.e. from the URL) to it.

When you point your browser to the URL http://localhost:4567/monstas/Elizabeth your application will say “Hello Elizabeth!”, when you go to http://localhost:4567/monstas/Juliane your application will say “Hello Juliane!”, and so on.

Let’s inspect the params hash, and return this string as the response body:

get "/monstas/:name" do
  params.inspect
end

If you restart your application, and reload the page in your browser, then it should display something like this:

{"name"=>"monstas"}

So this confirms that params is a hash, and the key "name" has the value "monstas" set. In fact, it isn’t really a hash, just something very similar to a hash called Sinatra::IndifferentHash which is exacly like a hash, with a small trick applied so that we can access the keys indistinctly as strings or symbols. That’s why we could use params[:name] in the previous example.

This is pretty cool.

The params hash can contain more than matches from the URL. You’ll later see that it also contains any data sent from HTML forms as part of the HTTP request. As well as any query params that can be part of the URL (separated with a question mark ?).

But for now it’s good to know that Sinatra adds matches from the path pattern to the params hash.