razzi.abuissa.net

Razzi's guide to sinatra

Sinatra is a great Ruby web micro-framework.

Its docs are good! Here’s my minimal getting started guide.

Put this in app.rb:

require 'sinatra'

get '/' do
  'homepage'
end

Set up a bundle project:

$ bundle init

Make the bundle path local see explanation:

$ bundle config path --local vendor/bundle

In a moment we’ll install puma which needs this apt library:

$ sudo apt install -y ruby-dev

Add Sinatra and ruby web server dependencies:

$ bundle add sinatra rackup puma

Run the app:

$ bundle exec ruby app.rb
== Sinatra (v4.1.1) has taken the stage on 4567 for development with backup from Puma
Puma starting in single mode...
* Puma version: 6.6.0 ("Return to Forever")
* Ruby version: ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux-gnu]
*  Min threads: 0
*  Max threads: 5
*  Environment: development
*          PID: 49385
* Listening on http://127.0.0.1:4567
* Listening on http://[::1]:4567
Use Ctrl-C to stop

And it’s running on http://localhost:4567/ ! I’d have thought 5678 would have worked better with the music theme ;)

If you do actually want to change the port, add the following line to your app.rb:

set :port, 8000

live reloading

You’ll notice that if you edit the code, it isn’t applied to the currently running server.

The official docs at https://sinatrarb.com/faq.html#reloading recommend using an out-of-process approach (a rerun executable), but I find that it doesn’t reload as fast as the sinatra-contrib reloader.

You can install it like so:

$ bundle add sinatra-contrib

Then you can enable live reloading by adding this require under require 'sinatra':

require 'sinatra/reloader'

It’s deprecated but as I find it to be the best option, I hope they don’t take it away.

Note that you wouldn’t want this to run on your production server. (Still TODO is a guide to deploying a ruby application.)

templating

You’ll probably want to template a response. You can do it inline:

get '/' do
  template = "<%= 3 + 3 %>"
  erb template
end

But you’ll probably want to move it to its own file views/index.erb:

# app.rb:
get '/' do
  erb :index
end

# views/index.erb:
<%= 3 + 3 %>

To pass variables to the template, put them in a :locals hash:

get '/' do
  message = 'hi'
  erb :index, :locals => { message: }
end

# views/index.erb:
The message is <%= message %>

(this example is using the hash key-value punning syntax { message: })

Result:

$ curl localhost:8000
Message is: hi