Ruby - How to Build a Simple Sinatra App
Intro
Web-based applications are all the rage these days. You can apply your Ruby knowledge to build useful applications easily with a great DSL called Sinatra.
With Sinatra, you basically associate Ruby code blocks with URL routes. For example, run some method whenever someone requests “/” on your website.
For our example, we’re going to write a simple web application that just returns the client’s IP address. You’ve likely seen this functionality elsewhere on the web. It’s really useful for testing that a VPN is working, or figuring out what IP address you need to allow through a firewall.
Let’s get started!
Setup The Environment
You should already have a working Ruby installed with rubygems and bundler setup. I always like to make a gem for my applications, so let’s create one. You can call yours whatever you want, but I’m going to call mine ipecho
:
Hop into the gem directory and take a look at what we’ve got:
Edit the Gemspec
The first thing I do after creating a new gem, is update the gemspec file. We need to fill out some metadata and add some runtime dependencies to build or gem. You need to fill out the TODO fields for rubygems to build your gem. Obviously, you can change the name and metadata from what I have here. The most important thing is the add_runtime_dependency
. In production, you’ll want to be more specific about the version to avoid compatibility and security problems. This simple specification will work fine for development:
Creating the Sinatra App
Let’s start by creating a file called app.rb
in the gem directory. We’ll step through piece-by-piece and show you the entire app.rb
file at the end:
Require Sinatra
Rather straightforward, but we need to require
Sinatra before we can use it. You can add other gems here when you extend this example.
Subclassing Sinatra::Base
So first, we create a subclass of Sinatra::Base
for our app. We’ll stick it in the namespace of our ipecho
gem, so we’ll call it Ipecho::App
.
Within this class, we define our app.
Sinatra Configuration
First, we set a basic :bind
config to tell Ruby to bind our server to 0.0.0.0
. Sinatra has a lot of other configuration directives. It turns out that 0.0.0.0
is the default value for :bind
anyways, but it’s there for illustration.
Route Lambdas
Next, we define a lambda
and assign it to a variable, echo_ip_address
. The lambda is just a block of code that will run when the user makes a request. This one is dead simple, it just fetches the ip
attribute out of request
, and returns that string. The user will see this string (their IP address) in the browser.
request
is a Rack Request
object with other interesting information you can print out if you want.
You can make more route lambdas, but this is all we need for the demo. Now let’s hook them up to requests.
Hooking up the Lambdas
You can see at the very bottom of the Ipecho::App
class, we assign the echo_ip_address
lambda to any GET
requests for /
. You can assign the same lambda to multiple requests if you want, and you can use other verbs like put
and post
as well.
Putting it All Together
OK, here it is altogether in one app.rb
file:
Running the App
Rackup Configuration
First, we need to create our rackup config file, config.ru
:
Now, just execute rackup
and it should start up.
Open up http://localhost:9292 and you should see your IP address. If your browser is running on the same computer as your server, you’ll likely see 127.0.0.1
, but if your server is in the cloud you should see your public address. Members on your LAN will also able to see their addresses if they can reach your port 9292.
Anyways, I hope you had fun creating this simple Sinatra application. I’ve had a similar application running at portscan.io that does a port scan on the requesting client’s IP address. I’m sure you can think of other more interesting things to do with the Sinatra DSL. If you build something cool or need a hand, feel free to drop me a line.
Thanks for reading!