The Complete Magazine on Open Source

Exploring Sinatra

2.11K 0

This basic introduction to Sinatra can be used by interested readers as a starting point, from where they can move on to the vast resources online.

Ruby, a mature language, is used in many applications but Web development is what it is mostly used for. Whenever someone recommends Ruby for Web development, the first thing that comes to mind is Ruby on Rails. Granted, it’s a great Web framework for rapid prototyping, and has excellent documentation, tooling and community, but there are times when using Rails is an overkill—like when you want a simple solution without having to navigate between files and directories and just want the work done. Or, when you want a quick solution to a problem but don’t want to fiddle through configurations. For such cases, Sinatra might be the right tool for you.
Sinatra is named after the famous American singer and actor, Frank Sinatra. It was designed and developed by Blake Mizerany, with a huge list of contributors and backing from many companies like Travis CI. Sinatra is a library and not a framework, which means it doesn’t do many things under the hood and let’s you handle the logic, which is a great thing if you want control.

Installation
Sinatra is easy to install. The only obvious requirement is Ruby. If you don’t have Ruby installed, try rbenv or rvm, both of which let you manage and install multiple Ruby versions. Installing it is as easy as using the following command:

gem install sinatra

Basic use cases
Sinatra is a DSL (domain specific language), which helps in reducing the effort to churn out a Web application. To run Sinatra locally, there is no configuration needed.

require ‘sinatra’

# Associates Root of the website with following code block when a get request is processed

get ‘/’ do
“Hello World”
End

Sinatra executes a code block by matching it with an HTTP verb like GET, POST and a URL location like /user, /important. In the above example, when some program makes a GET request to the root ‘/’, it will execute the code block and ‘Hello World’ will be returned by the server to the user, because in Ruby, the last statement is treated as the return statement.
To run the code, type the following command:

ruby hello.rb

The following output should be visible with some variation, depending on your version of Ruby and the backend server:

== Sinatra (v1.4.8) has taken the stage on 4567 for development with backup from Puma

Puma starting in single mode...
* Version 3.6.2 (ruby 2.2.4-p230), codename: Sleepy Sunday Serenity
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:4567
Use Ctrl-C to stop

If you open http://localhost:4567 you will see a ‘Hello World’ message.
Sinatra has a params hash to capture parameters passed to the route. A small excerpt is shown below:

post ‘/secret’ do 
“Message is #{params[:message]} “
end

The following code displays the parameter named message which was POSTed to /secret. All the parameters sent to a route are available in hash named params. If we make a POST request with the message ‘meet me at Coffee Shop’ as follows:

curl --request POST --url ‘http://localhost:4567/secret?message=meet%20me%20at%20Coffee%20shop’

…we will get the following output:

Message is meet me at Coffee shop

Sinatra routes can contain regular expressions, named parameters and wild card expressions, as well.

get '/send/:room/?' do
"Sending message to room no #{params[:room]}"
end

This time we don’t need to pass the parameter explicitly; it has become a part of the URL itself and it will just work, and like in the previous instance, the parameters are available via params hash. The interesting bit in the route is ‘/?’; it is used so that the route will work with and without the trailing slash, so that both http://localhost:4567/42 and http://localhost:456/42/ are legal.

curl --request GET --url http://localhost:4567/send/42/

Sending message to room no 42

Splat (*), or what is commonly known as the wildcard operator, will allow anything and is accessible via a special parameter named splat which is an array of all the values captured by splat against *.

get ‘/mix/*/with/*/?’ do 
“I have #{params[:splat]} and I am going to mix #{params[:splat].first} with #{params[:splat].last} “

end

curl --request GET --url http://localhost:4567/mix/apple/with/oranges/

I have ["apple", "oranges"] and I am going to mix apple with oranges

There are many ways to play with routes, but covering them all would be beyond the scope of this article.
One cool thing that you can quickly do with Sinatra is make APIs, which generally don’t require any interface and most of them are stateless. In the following example, we will make a simple API that returns all environment variables available on the machine in JSON format. For JSON conversion, we need a JSON parser and generator, which Ruby already ships with.
Content type tells Sinatra to explicitly specify itself in the response header.

# Load the JSON library
require ‘json’


get ‘/json’ do 
content_type :json
ENV.to_h.to_json # To json converts the ENV which was converted into hash to json
end

curl --request GET --url http://localhost:4567/json

The output may vary depending on the system and configuration:

{
"PWD": "/home/jatin/Area_51/sinatra_example",
"HOME": "/home/jatin",
"LC_CTYPE": "en_US.UTF-8",
"BROWSER": "/usr/bin/chromium",
"JOURNAL_STREAM": "8:20822",
"XDG_SESSION_TYPE": "x11",
"XDG_SESSION_DESKTOP": "gnome-xorg",
"GJS_DEBUG_OUTPUT": "stderr",
"RBENV_DIR": "/home/jatin/Area_51/sinatra_example",
"MAIL": "/var/spool/mail/jatin",
"WINDOWPATH": "2",
"TERM": "xterm-256color",
"SHELL": "/usr/bin/zsh

}

Sinatra can handle views and templates as well, and they are pretty simple. So, it’s good if you want to make user-facing applications.

Note: Most of the code used in the article is also available at https://github.com/jatindhankhar/sinatra_example.

Plugins and libraries
There are innumerable libraries available for Ruby, in general, and almost of all them will work with Sinatra but there are some, like those listed below, that are a ‘must have’.
Shotgun: It lets you reload the server on file changes, enabling faster development.
Byebug: This library lets you debug an issue by pausing the request and providing a full-blown REPL to investigate.
Sinatra-Cross-Origin: This library lets you handle Cross Domain Origin Resource Sharing (CORS), which is very useful if you are making a web SDK for others to use.
There are many extensions available at http://www.sinatrarb.com/extensions-wild.html that might help.