Rolling With Sinatra

Share this article

When it comes to web development, Sinatra is amazingly flexible. Unlike Rails, it isn’t opinionated in the slightest and basically lets you make all the design decisions. It does have some conventions, such as automatically looking for view templates in the ‘views’ folder, but virtually all of these default settings can easily be changed. Sinatra doesn’t make any decisions for you – you literally start with a blank slate. Konstantin Haase, maintainer of Sinatra, refers to this as Sinatra’s biggest strength but also its biggest weakness, since Sinatra isn’t going to stop you from writing bad code. Given that there are so many choices that you can make when creating an application in Sinatra, I decided to ask around and find out how people roll when they use it. I asked the following questions:
  • Do you have a set folder structure or coding patterns?
  • Do you tend to use classic or modular style?
  • Do you use any bootstrap code?
  • Do you ever use inline-views?
  • Anything Else?
I got some interesting responses that I thought I’d share on here. You can also view the whole thread here: https://groups.google.com/forum/#!msg/sinatrarb/BFAXCCK3D8I/mXLv6YDoBcAJ

Do you have a set folder structure or coding patterns?

Sinatra has no directory structure to speak of – you don’t even get an application folder, unless you create it yourself. As mentioned earlier, it has some nice defaults like automatically keeping view templates in the ‘views’ directory and public assets in the ‘public’ directory and using a file called layout.erb as the default layout. All of these can be easily changed using the set method, like so:
set :public_folder, 'assets'
set :views, 'templates'
set :erb, :layout => :base
A lot of the people I asked tended to use a Rails-like structure of ‘Models, Views and Controllers’ folders. They also tended to use a similar structure to that used by RubyGems with folders such as ‘lib,test/spec/, public’. Another popular technique was to use a file called ‘init.rb’ that requires all the other relevant files. This makes it useful for running your app from the console or during tests. Blake Mizerany, the creator of Sinatra, said that he preferred to use a single directory where all of his modules and views were kept in one place. I like to keep my folder strucutre very simple, usually with a file called main.rb that contians most of the application code. I will then usually use a public and views folder and then leave it at that. Any extra files will usually go in the root directory.

Do you tend to use classic or modular style?

Sinatra has two distinct styles of coding – classic and modular. Most examples that you find on the web are classic applications, here is another example:
require 'sinatra'

get '/hello' do
  "Hello World!"
end
The same app done modular style would look like this:
require 'sinatra/base'

class Hello < Sinatra::Base
  get '/hello' do
   "Hello World!"  
  end
end
As you can see, the main difference in a modular-style application is that all of the code is wrapped in a class that is subclassed from Sinatra::Base. Whereas, in a classic application you just require ‘sinatra’ and get on with it – this tends to be the style used in most onine tutorials. Most people who responded to my questions preferred to use the modular style. Josh Cheek mentioned that classic style is useful for demonstrating techniques (hence the reason why it’s probably used for most examples on the web). John Nunemaker (GitHub) said:
I would never use classic anymore. Too pollutive.
This refers to the fact that the global namespace can become polluted with methods of the same name. This is not usually a problem when writing small applications, but can become more of an issue if you are writing a large modular application (particularly if different people are working on different modules). Jason Rogers also pointed out a useful technique that helps map your urls to a specific class:
If I’m going to have resources split out under separate paths (eg. “/admin”, “/api”, etc.) I will use a modular approach and map the individual modules in Rack under their path name.
This can be done in the config.ru file using Rack’s map method, like so:
require 'sinatra/base'
require './main'

map('/admin') { run adminController }
map('/api') { run apiController }
Personally, I love the to use classic-style applications and think they are very direct, allowing you to get started writing code quickly. The downsides are few and it is very easy to move over to a modular-style application if it grows bigger. If you want to package up your application as a gem or extension, however, then you really do need to go for the modular-style. I should point out that the developers of Sinatra remain committed to keeping the two different styles of application.

Do you use any bootstrap code?

Rails has a lot of code generators that will quickly get you up and running with various bootstrap code. I wondered if people had used anything similar to get their projects off the ground in Sinatra. Geoffrey Grosenbach used a little bit of bootstrap code to save setting up the same things over and over:
Sometimes I start from an existing simple Git repo, especially if I’m going to be using Backbone or other frameworks that need some setup.
Others liked to include things like Knockout.js and Twitter Bootstrap initially (presumablly to make the front end development easier). User diminish mentioned a code generation tool on Sinatra’s Google Groups page that was in development and sounded interesting. It would be good to see if any progress had been made with this. In my own Sinatra projects, I don’t tend to use any bootstap or generator code, as it’s so easy to get started with a project. Although, I have considered putting together a minimalistic file structure that includes some basic CSS and layouts that I usually use. There are a number of similar projects available such as Sinatra-Bootstrap-Starter, although these start to take some of the design decisions away from you – always better to develop your own that works for you!

Do you ever use inline-views?

Inline views let you keep all your view code in the same file as your app. Here’s a quick example:
require 'sinatra'

get '/hello/:name' do
  @name = params[:name]
  erb :hello
end

__END__

@@hello
<h1>Hello!</h1>
In this example, the view called ‘hello’ is placed after the __END__ declaration. All views are marked by starting with ‘@@’ followed by the name of the template. Most people didn’t use these, although one notable exception was Blake Mizerany, who liked to use them for small applications:
I’ll use inline templates when there are only a few and they are small
Personally, I often like to use inline views and I think they are one of Sinatra’s coolest features. When I’m playing around with some code or starting a project off, I really like the fact that I can create something all from within one file. In fact, Avdi Grimm managed to create a Sinatra application that had everything in the same file, including tests! (http://devver.wordpress.com/2009/05/13/single-file-sinatra-apps-with-specs-baked-in/)

Anything Else?

A lot of people use Sinatra differently and the overriding opinion was that they wanted to choose their own way of doing things. Geoffrey Grosenbach likes how Sinatra exposes how things work more and therefore helps you to learn those skills to a greater degree:
Learning and using Sinatra helped me master other tasks better (like setting up tests).
He also thought that the extra effort paid off with faster development time:
Even though there’s a bit of work, I love the speed of working with Sinatra.
He also went on to say:
I rarely use Rails generators, and often use a NoSQL database, so Sinatra is perfect for most of the apps I want to write.
Rick Olson (GitHub), liked to use
Lots of Mustache and Rack-Test
This is different to what other people use, but perfectly easy to do with Sinatra’s flexibility. As for the point made by some people that Sinatra lacks functionality, Jason Rogers counters with:
I’d say that’s what gems are for. One of the great benefits of Sinatra is its lack of opinions.
He also pointed out that even in this small sample, people choose to use Sinatra differently, meaning that everybody could not possibly be satisfied with a one-size fits all approach. This gets to the heart of what Sinatra is all about – letting you choose your own way of doing things, perfect for control freaks who like things done a particular way! soldier.coder used a great metaphor for explaining why you might want to use the fine-grained solution of choosing your own gems offered by Sinatra:
Why not just use rails? Rails is like bringing a destroyer to a pirate/hostage situation when you really need a Special Forces or Seal team. Large applications? Large apps is kind of misleading as it really depends on the break down of how it is organized. Large and monolithic is very different than large and modular. Writing software as a service encourages separation of concerns. Sinatra seems ideal for such separation.
This is a good point. Sinatra’s modular style, actively encourages you to write modular code that can pieced together in large applications. There are a number of advantages to this – you can reuse modules in other applications, you can remove a module if it isn’t required any longer, different teams can work independently on separte modules. Blake Mizerany also pointed out the benefit of a bit of advance planning:
In general, I like to put a good amount of forethought into what I’m doing; This allows me to keep things simple.
With some planning in advance, you can set up your project in such a way that its design remains simple and Sinatra will let you do this. I think all of the feedback I received helps to highlight just why Sinatra is so flexible: If you want to get something up and running quickly then you can fire up a classic application with inline views in no time. If you want to build a big application then you can go modular with your own bespoke file structure and separate all of your concerns. Most of these topics are covered in greater depth in my new book, Jump Start Sinatra. I hope this article has given a taste of the many different ways there are to roll with Sinatra. What about you? If you’ve used Sinatra, how do you roll? If you haven’t tried Sinatra yet, then has this post helped to show what Sinatra is capable of? Don’t forget, Jump Start Sinatra will be out very soon. Go sign up to be notified when it’s ready!

Frequently Asked Questions about Sinatra

What is Sinatra and how does it differ from other web application libraries?

Sinatra is a Domain Specific Language (DSL) for quickly creating web applications in Ruby. Unlike other web application libraries such as Rails, Sinatra is minimalistic and flexible. It doesn’t follow the typical Model-View-Controller (MVC) pattern, instead, it allows developers to take a more DIY approach to building their applications. This makes Sinatra a great choice for smaller, simpler web applications where a full-fledged framework like Rails might be overkill.

How do I install Sinatra?

Sinatra is a gem, so you can install it using Ruby’s gem package manager. Simply run the command gem install sinatra in your terminal. Make sure you have Ruby and RubyGems installed on your system before you try to install Sinatra.

How do I create a simple Sinatra application?

Creating a Sinatra application is straightforward. First, require the Sinatra gem in your Ruby file. Then, define a route and its corresponding action. Here’s a simple example:

require 'sinatra'

get '/' do
'Hello, world!'
end

How do I use templates in Sinatra?

Sinatra supports templates via several templating languages, including ERB and Haml. To use a template, you simply need to define a route that renders the template. Here’s an example using ERB:

get '/hello' do
@name = 'World'
erb :hello
end

How do I handle form data in Sinatra?

Sinatra makes it easy to handle form data. You can access the data sent via a form using the params hash. Here’s an example:

post '/form' do
"You said '#{params[:message]}'"
end

How do I use sessions in Sinatra?

Sinatra provides built-in support for sessions. To use sessions, you need to enable them in your application. Here’s how:

enable :sessions

get '/' do
session[:message] = 'Hello, world!'
redirect '/show'
end

get '/show' do
session[:message]
end

How do I test a Sinatra application?

Sinatra applications can be tested using a variety of tools, including Rack::Test, RSpec, and Capybara. Here’s an example of a simple test using Rack::Test:

require 'test/unit'
require 'rack/test'
require_relative 'myapp'

class MyAppTest < Test::Unit::TestCase
include Rack::Test::Methods

def app
Sinatra::Application
end

def test_my_default
get '/'
assert last_response.ok?
assert_equal 'Hello, World!', last_response.body
end
end

How do I deploy a Sinatra application?

Sinatra applications can be deployed on any server that supports Rack applications. This includes popular platforms like Heroku, AWS, and Google Cloud. The exact steps for deployment depend on the platform you’re using.

How do I use databases in Sinatra?

Sinatra doesn’t come with built-in support for databases, but it’s easy to integrate with libraries like ActiveRecord or DataMapper. Here’s an example of how to use ActiveRecord with Sinatra:

require 'sinatra'
require 'active_record'

ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: 'db.sqlite3'
)

class Post < ActiveRecord::Base
end

get '/' do
@posts = Post.all
erb :index
end

How do I handle errors in Sinatra?

Sinatra provides several ways to handle errors. You can define custom error pages using the error method, or you can use the halt method to stop processing a request and return a specific response. Here’s an example:

get '/divide' do
divisor = params[:divisor].to_i
halt 400, 'Invalid divisor' if divisor.zero?
"100 divided by #{divisor} is #{100 / divisor}"
end

Darren JonesDarren Jones
View Author

Darren loves building web apps and coding in JavaScript, Haskell and Ruby. He is the author of Learn to Code using JavaScript, JavaScript: Novice to Ninja and Jump Start Sinatra.He is also the creator of Nanny State, a tiny alternative to React. He can be found on Twitter @daz4126.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week