
Lotus, a web framework for Ruby - krasnoukhov
http://lucaguidi.com/2014/06/23/introducing-lotus.html
======
Eleopteryx
This is depressingly similar to what I was aiming for when I recently began
work on: [https://github.com/lean-framework/lean](https://github.com/lean-
framework/lean) (I feel like this happens to me a lot.)

Rails controllers are hard to test because actions aren't designed to be
testable objects.

ActiveRecord models become monolithic because there's no separation of
instantiation, validation, persistence, or retrieval.

I originally experimented with building a Rails app that forgoes ActiveRecord
to a large extent; using plain Ruby classes + Virtus gem to separate the
aforementioned concerns depending on context.

I was pretty satisfied with the number of design headaches I was able to
avoid, which is when I started to create a framework around the aforementioned
paradigms.

Not sure if I just lost my motivation or not, but I'm glad I'm not alone.

~~~
yid
> This is depressingly similar

In graduate school, many a moon ago, my advisor would say that this is
validation of the idea, so one should be happy to be on the right track.

~~~
Eleopteryx
Thanks for the de-demotivation.

~~~
mattgreenrocks
It isn't zero sum. There's still substantial design space to explore.

Lotus being received well just means people are ready for the idea. That may
not have been the case in 2011, for instance.

~~~
Eleopteryx
I think I was misunderstood. By de-demotivation I meant re-motivation :)

------
emiller829
This is a promising start. I've felt for a while now that we need some strong
alternatives to Rails for the folks who feel like the Rails Way and the Ruby
Way don't always get along.

It still feels a bit DSL-centric from the examples I've seen thus far, and
haven't dug into things to see what the generated Ruby looks like -- but if
it's anything close to simple, this is something that has a chance to become
an important part of the Ruby ecosystem.

If nothing else, it's great to see things like this because they provide
concrete example code for discussions that (IMHO) need to happen.

~~~
jrochkind1
For a while, I thought Sinatra was taking that role? It might be interesting
to think about what people are looking for that's neither Sinatra nor Rails,
or why Sinatra didn't live up to what people were hoping (if people think
that).

Sometimes I think some of this is just utopian grass-is-greener thinking.
While there are _many_ things I'd do differently in Rails if I had the choice
(some but certainly not all of which the Rails core team probably agrees with,
if they had the chance to start over)...

...I think some of the "the thing we need is something _lighter weight_ than
Rails" thinking is basically wishful thinking. When you start with something
lighter weight, you (being me) generally find you need more than it offers,
and then you've got to go finding your own things to do those things, and when
these extra third party things end up not as high quality as you'd like, or
end up abandoned by their developers, or you end up spending many hours re-
inventing a wheel you're sure someone else has already invented.... either the
'lighter thing' ends up gaining weight, or you end up wishing it had.

Doesn't mean I agree with all of Rails choices about what to include, or how
to architect it. But I think people under-estimate how challenging it is to
hit the sweet spots, as if Rails core team just lacked the will or
intelligence or proper understanding or something, none of which I think they
lack. Still, certainly alternatives are great, testing grounds for other
possible ways of doing things are great, the more different things we see, the
better all of our architecting and coding gets, that's the only way to learn.

~~~
pmontra
For any project worth talking about Sinatra is too skinny. Basically you have
to hack your routing in about the same way you do with Node's Express,
enumerating the bindings between routes and methods. Obviously there are
clever ways to do it but you end up reimplementing the resourceful routes of
Rails.

Another problem is that you really want to use ActiveRecord to access the
database. Anything else it too painful. So you end up creating AR models and
you have to manually include them.

Finally there are views. I won't even enter into that.

Soon you end up with a worse engineered Rails. I've been using Sinatra only
for serving API requests for small projects. I won't touch it for anything
else.

~~~
auxbuss
I've built large projects with Sinatra. I've done the same with Rails, many
times. The idea that you can't build something substantial with Sinatra is
hogwash.

It is not a given that Active Record -- I presume you mean the pattern -- is
necessary, but AR is available in Sequel, which is the usual choice of ORM
when build with Sinatra. (In addition, Sequel has myriad additional benefits
over Rails' ActiveRecord, particularly if you want to use raw SQL.)

Views in Sinatra are not much different to Rails, so whatever issue you have,
I'm unclear what they are.

If you end up engineering a worse Rails then, as they say, you are doing it
wrong.

As I mentioned, I use both, and you can achieve the same results with either.
They are both, in effect, rack stacks these days; they simply have different
conventions, one more opinionated than the other.

------
lobster_johnson
Looks nice. I particularly like the ORM, which seems well-designed compared to
ActiveRecord.

That said, I have a distinct feeling this is too little, too late. I and my
teams have long migrated away from frameworks, to microservices, or what some
people call SOA, and we are not looking back. I strongly encourage this design
over the old monolithic Rails approach.

These are mostly small, highly specialized Sinatra backends that speak data
only through REST APIs. For such backends, you don't need views, and you
hardly need models; when "deconstructing" your data model into multiple
backends, the data model for each microservice often becomes absurdly simple.
Mostly you need a simple way to express REST endpoints. Sinatra is very simple
and doesn't support any abstraction, but that's mostly a good thing. And you
can split your API across multiple files easily. The backends are getting so
simple that it's starting to look very tempting to migrate to Go, where we
could get real performance and concurrency.

On the front end, I would still use Sinatra if it were a classic app -- you
can cobble together a "railsy" app with Sinatra by picking your template
system, database layer and so on -- but mostly these days we build Node.js
single-page apps that are sewn together with NPM and Browserify. Web app
development has never been as simple and elegant as it is when done this way.

~~~
jshen
Can you give done examples of the types of things these micro services do?

~~~
stevekemp
Not the poster, but I've written a few small sinatra-endpoints in my time.

For example I wrote a self-hosted comment-system, which is like a very basic
disqus service. The back-end is a simple sinatra service that just allows "GET
/comments" and "POST comments".
([http://github.com/skx/e-comments/](http://github.com/skx/e-comments/))

Last week I wrote a webhook-consumer, again using Sinatra. It receives a POST
from github, parses the received JSON, and adds some details of the body into
a queue for later processing.

Both services allow simple deployment and total may 50 lines of code each.

~~~
prawks
Sounds very similar to the things I've done with web.py in Python-land. Very
small, lightweight services that had no need for the power of Django. One such
example was a GET/POST/DELETE service to vote on submitted items (ideas, in
this case).

------
programminggeek
I think it's great to see someone make a run at a more decoupled ruby web app
approach. I hope it succeeds.

In my experience working on Obvious
([http://obvious.retromocha.com](http://obvious.retromocha.com)) it is hard to
get Ruby developers behind decoupled architectures because the large majority
aren't Ruby devs, they are Rails devs and Rails happens to be in Ruby.

Also, the larger group of developers doesn't like the idea of an app being a
giant collection of very small objects. It's like there is a gravity to the
notion of objects where we think of an object as something akin to a car, not
the thousands of parts that make up a car.

Last, I think the idea of MVC doesn't place the appropriate number of objects
for the different roles in normal request processing. At a reasonable point of
complexity really end up with routes, controllers, entities, data access
objects or repositories/adaptors, presenters, views, templates, helpers,
utilities/libs, and probably some other bits of random code in there somehow.
That doesn't fit the 3 role view of the world that is MVC.

Lotus does a better job than most of addressing such things, but I think the
MVC approach in general falls flat.

That lack of appropriate roles means that as programmers we invent a lot of
names, patterns, roles, etc. to fit what our code actually ends up doing.
That's why you see a lot of service patterns, presenter patterns, etc. being
attached to Rails. Everybody is duct taping their approach to the notion of
MVC, but very few are saying "what if we didn't see request processing as only
having 3 roles?"

MVC is better and cleaner than writing a page as one giant PHP file maybe, but
I've seen it fall down so many times that I no longer trust it as a useful
pattern or abstraction for expressing request processing and HTML string
manipulation in code.

In fact, if we were building command line apps and writing to files, I don't
think we would use MVC at all. But, since we're writing strings of HTML, it's
totally different right?

~~~
al2o3cr
I'm pretty sure they make a pill or something for that scorching case of
hasheritis. ;)

One problem I have with "decoupled" architectures is that the only way you can
sensibly interop with everything from RDBMS to flat JSON files is if you treat
the RDBMS _as_ a flat file. For instance, the sample Twitter clone treats
every available DB as a plain key-value store.

~~~
regularfry
> One problem I have with "decoupled" architectures is that the only way you
> can sensibly interop with everything from RDBMS to flat JSON files is if you
> treat the RDBMS as a flat file.

The Repository pattern is what you're looking for.

------
deedubaya
This is an interesting attempt. It has Sinatra like simplicity, providing the
modular architecture that was promised with the Merb + Rails merger.

At the very least, this will spark some interesting conversations and ideas.

------
mrinterweb
By what I've seen I like the spirit of Lotus, but I sense a movement away from
complete web frameworks to pure API back-ends with the emergence of great
single page JS frameworks like Ember. One ruby one that I like is
[https://intridea.github.io/grape/](https://intridea.github.io/grape/). One
interesting node API framework I mean to try is
[http://loopback.io/](http://loopback.io/).

~~~
shime
Yes, I also think that the future of backend development is micro services
communicating over defined HTTP API endpoints or other message protocols.

If you look closely, rendering presentation layer on the server side and then
sending it to the client is a hack and we've been doing it for a long time.
It's time for changes.

~~~
Smudge
> If you look closely, rendering presentation layer on the server side and
> then sending it to the client is a hack and we've been doing it for a long
> time. It's time for changes.

From the view/presentation layer's perspective, it shouldn't matter where the
rendering happens, and as a programmer working on these systems I'm tired of
baking assumptions about the data layer into the view layer.

I actually think there's a best-of-both-worlds solution that we'll converge on
at some point, which is this:

We have the option of rendering in both locations with the same code.

This allows the initial render to be offloaded to the server (so that the
app's initial state is totally established and can be sent along with the app
itself in a single HTTP request), and then subsequent rendering updates could
happen mostly client-side (fetching only the raw data from the server where
necessary).

This allows the JS-everywhere crowd to build their entire app as if all logic
is running in-browser (with only a basic API on the server), but it appeases
the more old-fashioned developers who want to be able to construct mappings
between URLs and actual HTML documents (that don't have to be spun up and re-
constructed using client-side scripting). There's obviously a huge debate here
as to whether or not the latter is worth it, but I'd say it would be nice if
only so that I don't need to have a flash of unloaded content or a "loading"
indicator before the app is ready to be used.

I also don't like having to use PhantomJS to scrape data from a website that
could very easily consist of HTML documents instead of a blob of JS, but
that's probably not enough to affect most people's opinions.

------
jaredcwhite
I'm all for new frameworks that emphasize different ideas and philosophies. If
nobody ever tried experimenting with a new approach, we wouldn't have Rails in
the first place. So kudos to Luca and his fine work in developing Lotus. I
like much of what I see.

That being said, I feel like YARWF (Yet Another Ruby Web Framework) is not the
most pressing matter in the web space today, and I take exception to the
notion that this is a complete web framework. It's not. A complete web
framework has client-side components that facilitate two-way communication
to/from the server, data binding, HTML5 history state-based page/view
swapping, etc. In other words, the type of stuff being addressed by Angular,
etc. At this point I wouldn't even characterize Rails itself as a "complete
web framework"...it's proven itself to be incomplete and needs something more
to be added to it for this kind of stuff.

What's the solution? Well, most people in the Ruby world do the typical route
of a Ruby + Rails/whatever backend and a JS-based (or CoffeeScript-based)
frontend. But I don't like it. I want one language that works on both sides
and in fact allows OOP code sharing between the two.

That's why I'm so bullish on Opal ([http://opalrb.org](http://opalrb.org)) --
Ruby-to-JS compiler. It may not be perfect, but it's usable and it's here now.
What we need is a framework built on top of Opal that is to the client what
Rails, or Lotus, is to the server. Then I think we can safely say that we have
a complete web framework solution for Ruby. Until then...not quite.

~~~
thecoffman
>A complete web framework has client-side components that facilitate two-way
communication to/from the server, data binding, HTML5 history state-based
page/view swapping, etc. In other words, the type of stuff being addressed by
Angular, etc.

No. I can't possibly disagree with this any more strongly.

I'm probably on the wrong side of history here, but Javascript absolutely
should _not_ be a requirement for using a website. If your website doesn't
work with NoScript turned on, I won't utilize it. Full stop.

In my mind Javascript should be used for progressive enhancement for those
users that opt to enable it (or I suppose more correctly: choose not to
disable it). Building a thick client web app is the fastest route to ensuring
I won't use it.

~~~
Igglyboo
>If your website doesn't work with NoScript turned on, I won't utilize it.

You're definitely in the minority then, most users don't even know what
javascript is let alone NoScript. I find it ridiculous that people are arguing
against javascript, we're using a computer and not allowing it to run code.

~~~
mercer
I was, and am, mostly on the side that argues that client-side javascript
support can be assumed to such a degree that it can safely be considered
requirement in a lot of cases.

However, I do have some reservations of a more 'ideological' nature when it
comes to requiring javascript when it isn't strictly necessary.

I still believe one of the most powerful things about the web is the
(relative) simplicity of the request/response server-side-rendering approach.
There are so many ways in which a web page can be consumed (scraped, read-
later-tools, etc.), within 'fair' boundaries of course. And this often falls
apart because of client-side javascript.

This is fine when it concerns a web-app that is specifically made for browsers
(where ideally there's also a public-facing API). But for most other things it
should not be necessary, and I believe it harms the possibilities of the open
web. And quite often I find that it deceases the usability in general (back-
button breakage, etc.).

Of course, my ideal solution is both server- and client-side support, used
appropriately, through something like React or PhantomJS.

~~~
EGreg
I'd be curious what you think of this:
[http://platform.qbix.com/guide/pages](http://platform.qbix.com/guide/pages)

------
jeltz
To me the examples look too wordy compared to sinatra or padrino. Like the
lack of auto loading though, the autoloading is my opinion a huge mistake in
rails and padrino.

------
herge
Whenever I hear lightweight and complete, I always wonder if they handle one
of the hardest things to do cleanly in web-apps: user authentication and
access control of resources. Does Lotus support this out of the box?

~~~
chrisdevereux
Slightly OT, but as a mobile guy who occasionally toys with server-side
programming, authentication is always where I get stuck. I'd like to see some
examples of how to implement authentication and sessions cleanly without too
much framework magic. Any pointers?

~~~
p8952
Rolling your own? This is as simple as it gets:
[http://128bitstudios.com/2011/11/21/authentication-with-
sina...](http://128bitstudios.com/2011/11/21/authentication-with-sinatra/)

If you want to make it even easier, use OmniAuth:
[http://recipes.sinatrarb.com/p/middleware/twitter_authentica...](http://recipes.sinatrarb.com/p/middleware/twitter_authentication_with_omniauth)

------
cies
Feels like Merb all over again!

Data Mapper, significantly less code, humble core-contributor.

Great work!

~~~
Eleopteryx
I really liked Merb, and stuck by it for some time. Rails 3 was supposed to be
Merb 2. It wasn't really, but Merb was still lost to the "merge".

------
hyperliner
Is it weird / bad karma to call this "Lotus"?

~~~
mrinterweb
You could make an example application called "Notes" with Lotus.

~~~
rbanffy
Or a spreadsheet and call it "123"...

Or even worse - a webmail app called "cc:Mail".

------
mdavidn
_Lotus::View is the first library for Ruby that marks a separation between
view objects and templates._

This is a great idea, but Lotus::View isn't the first. See Mustache.rb, for
example.

[https://github.com/defunkt/mustache](https://github.com/defunkt/mustache)

------
izietto
At the moment, if I should switch from Rails to another Ruby framework, the
killer feature would be a well integrated built-in streaming support
(something like Lotus::Live in this case), which nowadays is a must for a web
framework; otherwise the stability of Rails and the big community around it
(people, gems) would win against this project, as against the many other
current Ruby frameworks.

Anyway I wish good luck for this project, which was created by a person of the
same country of mine (Italy), of the same city (Rome) and which I met at the
only Ruby meeting ever done in Rome I suppose, a couple of years ago.

~~~
pmontra
Rails has
[http://api.rubyonrails.org/classes/ActionController/Streamin...](http://api.rubyonrails.org/classes/ActionController/Streaming.html)
which I never used. It seems that Lotus::Live isn't ready yet. I can't find
any docs for it so I don't know how they compare. Could you point me to an
URL. Thanks.

~~~
izietto
Yes, but ActionController::Streaming is not made for long pooling; what I mean
is 1) web sockets and/or server side events support and 2) Raisl streaming
helpers (models watching, client events, etc.); essentially, the good parts of
node.js frameworks.

Lotus::Live doesn't exist, it is a name example for the feature of which I
feel the missing.

------
tinco
Weird, I get the idea of defining a new web framework API, but why would you
build everything from scratch? There's loads of very good open source code out
there.

Why not fork DataMapper for Lotus::Model for example? Now you have some dodgy
hand rolled library that's probably not seen enough eyes to be really
production proof.

~~~
gkop
Lotus::Model apparently depends on
[https://github.com/jeremyevans/sequel](https://github.com/jeremyevans/sequel)
, which has been widely used in production similarly to DataMapper.

~~~
tinco
It seems you are right, my apologies, I clearly hadn't read deep enough.
Still, Sequel is just an SQL abstraction. DataMapper is exactly what
Lotus::Model is, a full model abstraction over databases, regardless of the
querying language.

Some years ago I even implemented an XQuery querying backend for DataMapper,
it was not much work at all, at a time where AR still had SQL code all through
the base and Sequel was just in low profile development.

~~~
dragonwriter
> It seems you are right, my apologies, I clearly hadn't read deep enough.
> Still, Sequel is just an SQL abstraction. DataMapper is exactly what
> Lotus::Model is, a full model abstraction over databases, regardless of the
> querying language.

AFAICT from reading the Sequel code (and especially the code for the existing
adapters), there's no real hard dependency on SQL (since the adapter both
generates and applies the query string), though there is a dependency on being
able to map back and forth to SQL-like operations.

It shouldn't be impossible to write a driver for a non-SQL backend for Sequel,
though it seems like it would be progressively harder the farther from the
assumptions common to SQL its operation was.

~~~
jeremyevans
Correct, it's not impossible, there was a proof of concept mongo driver:
[https://github.com/jeremyevans/sequel-
mongo](https://github.com/jeremyevans/sequel-mongo) . I doubt it still works
with current Sequel, though, as I only coded it for a lightning talk in 2010.

------
kureikain
Thank for great fw.

I'm by no mean a Ruby expert but finding Sinatra is so simple to create
complex apps, and Rails is so complex atm to pick up. I'm making slowly
progress in Rails and always not sure if I done thing correctly in Rails way.

Lotus seems small enough, and good enouh, balance between Sinatra and Rails
for me.

Keep up the good work. Thanks.

~~~
liveoneggs
[http://www.padrinorb.com/](http://www.padrinorb.com/) check it out

~~~
kureikain
This is so cool. Built on top of Sinatra. So I can consider it like chaplin to
backbone, right? It creates an architecture on top of original framework.

------
rhgraysonii
I'm intrigued. Just signed up for the mailing list. Do you have any links to
applications built in Lotus?

~~~
fuadksd
There aren't many applications using the solution as a whole - as it was just
made public recenltly, but you can check some example applications used for
tests in the lotus repo:
[https://github.com/lotus/lotus/tree/master/test/fixtures/](https://github.com/lotus/lotus/tree/master/test/fixtures/)

------
chrisweekly
"We have infinite combinations. Small components have enormous advantadges in
terms of reusability."

Typo: "advantages". Nitpicking, I know, but it's in the first bolded sentence
on the page and it detracts from your messaging.

Cool project, good luck! :)

~~~
jamesbritt
Additional nitpick: "fewer" instead of "less", as in

"... you employ fewer DSLs and ..."

------
SeanLuke
This is a textbook example trademark infringement. IBM will not be humored.

~~~
matdes
uhhhhhh, I don't know if that's true.

Lotus was never a ruby web application framework. Guess Apple's going to have
to change the name of Swift because of that other programming language,
amirite?

~~~
SeanLuke
> Lotus was never a ruby web application framework.

A trademark's domain is nowhere near that specific. Recall that Apple was sued
by Apple Records because it made devices capable of being used "in the record
business".

> Guess Apple's going to have to change the name of Swift because of that
> other programming language, amirite?

Interesting that you say this. Apple certainly has a history of trademarking
its languages. Apple has trademarks on Objective-C and on AppleScript. Its
trademark on Dylan was abandoned and its trademark on Hypertalk was cancelled.
I'm guessing that Apple hasn't trademarked Swift because it can't: there are
two many other items already named Swift in the area. And the Swift scripting
language is hardly a threat to them: it's an NSF-funded research effort.

------
CarlHoerberg
sinatra/base, rack-urlmap and sequel, why would you want more fluff?

~~~
krasnoukhov
It looks like you're missing the point. As an example, I've built the adapter
for DynamoDB[1] so you can throw sequel out in matter of minutes even for
existing app, and most likely without any code change.

[1] [https://github.com/krasnoukhov/lotus-
dynamodb](https://github.com/krasnoukhov/lotus-dynamodb)

~~~
CarlHoerberg
No, if I choose Sequel
([http://sequel.jeremyevans.net](http://sequel.jeremyevans.net)) I want to use
all the power it gives me, not some lowest common denominator.. Also not all
projects needs models, you know, there's other data access patterns..

~~~
matdes
the concept of a model is not at all tied to a data access pattern unless you
subscribe to model = ActiveRecord::Base inheritor in the Rails world.

Model is a well-defined term in the domain-driven design world, as in "Domain
Model"

------
chrisweekly
"We have infinite combinations. Small components have enormous advantadges in
terms of reusability."

Typo: advantages.

Just a nit, but it does stand out since it's in the first bolded sentence on
the page.

------
jbeja
Isn't this old, i know i have heard of it several years ago.

------
ksec
It is rather interesting that most parts of Lotus has been posted on HN every
months, and yet dont even get more then 10 comment and a few points, not to
mention it was never on the HN frontpage.

Now all of a sudden it has 241 point. 134 comment.

------
DogeDogeDoge
How many of this type of frameworks we had. Padrino was there to fix something
but achieved nothing. It is better to focus on rails and fixing rails rather
than start a framework for everything.

Few doge years ago sinatra was faster than rails, today... not so obvious and
still offering much smaller set of functionality.

~~~
vidarh
> It is better to focus on rails and fixing rails

For many of us "fixing Rails" is easiest achieved by starting from scratch.

> and still offering much smaller set of functionality.

... and that is why I prefer Sinatra to Rails.

~~~
dragonwriter
> For many of us "fixing Rails" is easiest achieved by starting from scratch.

See, e.g., the road to Rails 3 through Merb.

