December 21, 2013
A Year’s Duet with Sinatra
Just about a year ago, I pushed something to GitHub called BareSinatraApp. Pleased with the simplicity of Sinatra but frustrated with the repetitiveness of setting up projects, I decided it was time to make a framework repeatable. Yeah, there are lots already (some of which are even Sinatra based), but none of them did exactly what i wanted, exactly the way I wanted.
I set out with some goals:
- Simple. My biggest complaint with Rails when I learned it was that I was really learning Ruby and Rails at the same time. I’ve noticed this about a lot of frameworks written in Node these days, as well. You don’t just learn Node, but Node and Express and some CSS compilation language. I wanted my little project to be good for someone who knows HTML/CSS/JS and Ruby, but hasn’t mashed the two together yet.
- Flexible. I made some picks about what to use, but I wanted to avoid being highly opinionated. That’s what drove me away from Rails, actually. For the record, I have no problem with it, and I’m not saying I’m right and anyone else is wrong. But I prefer to only have around what I need, and Rails brings too much baggage with it for my needs. Of course, I see the irony in packaging things up in the way I am, and how it’s starting to look like a Rails-esque project, but at least it’s built on what I want. And it’s for me, after all.
- Updated. I dropped the ball here. I wanted to keep the core project alive and bring in features as I fork it off for other things. But I have a plan for that.
- Documented. I learned programming by reading other people’s code. I got better by teaching other people how to code. I wanted my code to do both of those things in my absence. The Readme is the core of it, but I also try to document my code out, both technically and with design decisions.
- Stop Repeating Myself. That’s always the goal of code, right? I had spun up a lot of projects by copying a directory tree and purging extra files, so it made it sense to formalize that. Git lets me keep the core pieces in check, but I can add other stuff as appropriate. Also, authentication. Again, I could use a gem like Devise to manage that, but I wanted to keep it thin and learn how Warden works.
With that all in mind, last Christmas, I pushed up BareSinatraApp. Having used it on several smaller projects since then, I’m getting ready to push a big second version of it. It will be mostly cleaned up, more configurable than before, and have some newer technologies built in. Notably, I’m pulling out DataMapper in favor of ActiveRecord. This was one tough, and for a short while I debated going towards Sequel instead, but I wanted to make it a little magic despite goal #1. Plus, I really wanted to start getting in the habit of using UUIDs for my identity column instead of serial numbers for a few reasons, and I was most easily able to make this work with ActiveRecord and Postgres while still not writing a zillion lines of code (and raw SQL).
But wait – why UUIDs? Because I’m starting another new, ambitious project that will leverage this one to include remote syncing. Serial numbers are nice, but I wanted something globally unique so I can generate an ID remotely and be guaranteed uniqueness on the server. I really hope to be able to extract out that bit from my iOS project and share that, too. Tentatively named ActiveObjects, it will bring some of the magic of ActiveRecord to NSObjects, like introspection, persistent without Core Data, and remote syncing, but staying really out of the way, as in only requiring a few extra lines of code above creating plain objects. That’s not quite ready to go yet, but I’ll talk about it more as it gets closer.