Ruby Microframeworks: Camping and Cuba

Share this article

We all know about Ruby on Rails and a great majority of us know about Sinatra. But, there’s a thriving ecosystem of small web frameworks for Ruby outside these two. Don’t get me wrong; Sinatra is awesome! I’ve used it several times in the past, and, it has been great. However, it is important to learn about alternative approaches to the same problem. Get a headstart by installing the frameworks we’ll be covering: “gem install cuba camping” In this article, we’ll consider a couple of microframeworks in Ruby that take two substantially different approaches, compare them, and figure out their targeted use cases.

Cuba

Cuba is the microframework that is probably my favorite for a number of reasons that we’ll see pretty quickly. Let’s start off with the example application they provide: [gist id=”3694402″] Let’s say you save that to “hello_cuba.rb” That’s pretty simple code, but, it accomplishes a lot. Cuba.define takes a block, in which we can use the “on” method, to which we pass “get”. Then, inside another block, we can define the routes which respond to get requests. However, to run this, you can’t just type in “ruby hello_cuba.rb”. Instead, Cuba applications run with Rack. Rack is basically an interface that gets Ruby talking to a webserver. To get this working, you need a config.ru file (in the same location as the hello_cuba.rb file): [gist id=”3694444″] Now, to run this whole deal, type “rackup” into your Terminal (or, iTerm, Konsole, Powershell; we don’t judge here), and you should have a server running (probably at port 9292). Head on over to http://localhost:9292/, and, you should be redirected to /hello (check the URL bar), and should have a nice “Hello, world!” message on your browswer. You might think this whole rackup deal is pretty nonsensical – but, when you deploy an app, it makes life a ton easier. It becomes interesting when you try to write tests for Cuba apps. Check it out: [gist id=”3694456″] Coming from Sinatra, I think that’s incredible! Cuba has built-in support for writing concise, clean code for tests. Tests are something that are partly my coding workflow (they should be part of yours, too!), so I think this very convinient. As you can see, we fire a request, follow the redirect, and check the response (of course, you probably wouldn’t do this type of thing in very large pages, but, it works here). Let’s write some more URL matching code: [gist id=”3694526″] We added a post request which returns some pretty unhelpful JSON, and, added a couple of GET methods. The post routes work as expected; on post do, and, off you go. The /echo/:string route is very simple – you can go to something like localhost:9292/echo/rubysource, and, it will print “rubysource”. The /print route does the exact same thing, except, with URL parameters. Check out the syntax – you actually have to determine what you’ll use from the params before the block gets on its way. I personally think this helps me, for others, they might just like the params hash better. Cuba also packs in all sorts of security functions. All you have to do in order to get access to them is add “Cuba.use Rack::Protection” at the top of the application code. That prevents great majority of attacks from happening to you! It even comes with built-in support for templates! This is something I dearly miss in other small frameworks and I love Cuba for it. It makes life very easy (it is just a render call). Cuba’s philosophy is to write the web app in a couple of files, with most of everything global (just like Sinatra). I’ve used Cuba for a wide variety of things, such as a realtime, single page application to a small invoicing application. It has worked really well for me. However, performance bugs are difficult to track down and code seperation isn’t meant to be there. On to the next microframework!

Camping

Camping
follows a radically different philosophy than Sinatra and Cuba – it is an MVC framework. Instead of having everything all munged together, Camping’s philosophy says that it is far better to keep things seperated, but still, in one file. Here’s a super tiny application in Camping: [gist id=”3694695″] You can save this as “hello_camping.rb”, and run it with the “camping hello_camping.rb” command (assuming you installed camping like you should have at the beginning of the article), which should start a server on port 3301. If you slide on over to port 3301 with a browser, you should see “Hello, world!” displayed, fair and square. The code is a little bit more complicated than that of Cuba, but it isn’t too bad. We first tell Camping what our modules are going to come under, which leads to the Camping.goes :Hello line, then we define a module in which the controller classes will be defined. We only have one controller in our example, Index. Index derives from R '/', which means that it is called on the root route. Inside, we have a method that responds to the GET request and prints out the response. Camping has something called Markaby baked right in – it is basically a DSL in Ruby, so that markup can be generated by calling Ruby methods. Check it out: [gist id=”3694779″] We’ve defined a new Hello::Views module which has methods that correspond to view names. We can render these views from the controller, as we have done. So, this is the View-Controller portion of MVC ready to go! Running this (again, “camping filename.rb”) and pointing your browser in the correct direction, you should get a nice couple of headers, along with the title set. The Markaby DSL is remarkably complete and very useful, but for larger projects I still prefer HAML, ERB or Liquid. Routes in Camping are pretty simple (straight from the guide): [gist id=”3703680″] As you can see, the primary method of handling routes is via regular expressions. I’ve used this in the past with frameworks such as Django in Python, but I don’t find it as appealing for quick projects as the Sinatra/Cuba style routes. In the end, it is your choice and regular expressions can be far more powerful. There is an alternative way to match routes (with a patterns in the controller class names), but I’ve found this system very buggy and more pain than it’s worth. If you want to use it, check out the docs
. Speaking of docs, Camping probably has the most excellent docs I’ve seen for any web framework other than Flask (which is Python-based). Even though they don’t go in insane depth, they are easy to read and get you strated very quickly, so I highly encourage you to check them out. One of the coolest features of Camping are models. Here’s an example: [gist id=”3703750″] That’s not actually a complete web application (since we don’t have any controllers or views), but we can play around with in a console. Before that though, let’s take a look at the code. We have classes in the People::Models module, underwhich we store both migrations and models. The models must come before the migrations. As for migrations, if you know how they work in Rails, you know how they work here. Basically, the database querying parts of Rails (ActiveRecord) are reused in Camping, so much of the interface is the same. The migrations have version numbers specified by deriving from the “V” class, so, you can stack migrations one upon another by specifcing successive version numbers. To play around with this, run camping -C filename.rb in your terminal, which should get a console. Here’s what’s awesome – starting the console creates the database and runs the migrations! As for using the console, if you’ve used the Rails console (which is the best thing since sliced bread), the interface will feel very similar. Except that in order to reference models, you must use “People::ModelName”, so, in our case “People::Models::Person”. Stuff like the following is interesting to try out: [gist id=”3703793″] Comparing Camping with Cuba, it has a completely different ideology in terms of separation of concerns. There are many times where one will work better than the other in some sets of applications. Most of the time, for small projects, it doesn’t really matter – pick what you’re comfortable with. I really love Camping for its incredibly simple database interaction. This is harder with Cuba, since you have to use an external library, such as DataMapper. Also, the included benefit of having the excellent console is really amazing for catching bugs. I usually use Camping for small projects that I might have used Rails for, but have little time and want development done quickly. I’ve used it several times for weekend projects and the like.

Wrapping it up

I hope you enjoyed the whirlwhind tour of two absolutely excellent microframeworks that have been designed with a ton of thought. I’ve found these frameworks really useful, and I’ve tried to incorporate some of their ideas in other technologies that I work with (e.g. Rails). Thanks, and, do leave feedback!

Frequently Asked Questions about Ruby Microframeworks: Camping and Cuba

What are the key differences between Camping and Cuba?

Camping and Cuba are both Ruby microframeworks, but they have some key differences. Camping is a minimalist web framework, aiming to provide the most functionality with the least amount of code. It’s perfect for small applications and quick prototypes. On the other hand, Cuba is a microframework for web development originally inspired by Rum, a tiny but powerful mapper for Rack applications. It integrates many templates and testing frameworks, making it a more flexible choice for larger projects.

How do I get started with Camping?

To get started with Camping, you first need to install the gem by running gem install camping. Then, you can create a new Camping application by creating a new Ruby file and requiring the ‘camping’ gem at the top. From there, you can define your models, views, and controllers within the Camping namespace.

How do I get started with Cuba?

To start with Cuba, you need to install the gem by running gem install cuba. Then, create a new Ruby file and require the ‘cuba’ gem at the top. You can then define your routes within a Cuba block. Cuba also supports middleware, which allows you to add functionality to your application before the request hits your routes.

Can I use Rack middleware with Camping and Cuba?

Yes, both Camping and Cuba are built on top of Rack, which means you can use any Rack middleware with them. This allows you to add additional functionality to your application, such as logging, session management, and more.

How do I handle database connections in Camping?

Camping uses ActiveRecord for database connections, which is the same ORM used by Rails. You can define your database connection in a configuration block at the top of your application file. From there, you can define your models as subclasses of Camping::Model, and they will automatically have access to all of ActiveRecord’s features.

How do I handle database connections in Cuba?

Cuba doesn’t come with a built-in ORM, so you’re free to use whichever one you prefer. Many people choose to use Sequel with Cuba, as it’s a simple and flexible ORM that works well with smaller frameworks. To use Sequel, you’ll need to require the ‘sequel’ gem at the top of your application file and establish a connection using Sequel.connect.

How do I handle views in Camping?

In Camping, views are defined as methods on the module R in your application. These methods should return a string of HTML, which will be sent as the response to the client. Camping also supports ERB templates, which allow you to write HTML with embedded Ruby code.

How do I handle views in Cuba?

Cuba uses a similar approach to views as Camping. Views are defined as methods on your application, and they should return a string of HTML. However, Cuba also supports a wide range of template engines, including ERB, Haml, and Slim, giving you more flexibility in how you write your views.

How do I handle routing in Camping?

In Camping, routing is handled by defining methods on the module Controllers in your application. These methods should match the name of the route you want to define. For example, to define a route for ‘/about’, you would define a method called def about.

How do I handle routing in Cuba?

In Cuba, routing is handled within a Cuba block in your application file. You can define routes using the on method, which takes a string or regular expression to match against the request path. For example, to define a route for ‘/about’, you would write on 'about' do.

Dhaivat PandyaDhaivat Pandya
View Author

I'm a developer, math enthusiast and student.

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