Creating Web Application With Ruby Lotus

WARNING This is not your article if you are looking for information about the collaboration software made by IBM. Instead, this article is about Lotus, a new web framework written in Ruby.

Contents

What is Lotus

Lotus is a web framework that is being developed by relatively small team of lotus team. You can use Lotus and build a complete MVC web application just like Rails. Lotus is still under active development and not production ready as of Sep, 2014, but you can definitely use it to create a web application.

I fell in love with Lotus at first sight of the mission that Lotus tries to archive in the project page.

The page reads

Lotus is lightweight, fast and testable. It aims to bring back Object Oriented Programming to web development, leveraging on a stable API, a minimal DSL, and plain objects.

I felt this is what I was looking for (explained more later) and decided to use Lotus to create a small API server in my private project. Since there are not much documentation and information about Lotus in the wild yet, I sometimes had a hard time to figure out how to use it. But, I am recently getting used to the Lotus way so I’d like to share them in this and subsequent posts.

Why Lotus instead of Rails

Recent applications are built in modular way more than ever before. Whether you call this type of application architecture SOA or microservices, it is true that many recent great projects (my favorite example is Fylnn) are taking this design approach.

There are a few major benefits of taking this approach

  • more testability
  • more portability
  • more reusability
  • easier deployment

You will realize that it is not easy to accomplish all of these with Rails. Rails is definitely great, but the framework stack is huge and lots of things are built in. After all, Rails is a big framework, so not a good option if you want to create lots of small components.

You may think there are small frameworks such as Sinatra or rails-api. Yes, Sinatra is lightweight, but I recently prefer to pure ruby code than DSL because it gives me steep learning curve (meaning easy to learn). To be honest, I never tried rails-api by myself, but I am suspicious that it is lightweight because the base is still Rails. Let me know if you have different opinions.

As you can tell from Lotus github page, it is made of many components. You can easily bring one of components into your application. For example, you can just grab lotus-router and mixin to your Rack application to handle http request.

Although, Lotus is made modular way, you can still use it as fullstack web-framework with relatively small amount of codes. Apparently, Lotus steals many good designs from Rails such as CoC and that allows you to build applications easy.

So, my point in this section is this: Lotus is flexible but easy to use, so why not give it a shot?

Hopefully, this article helps you starting Lotus.

Creating one file application

Let’s make our first Lotus application. We will follow the example of one file application.

First, create a project directory. I am assuming that you set your current directory to this directory in the subsequent instructions.

1
mkdir onefileapp && cd onefileapp

Lotus does not publish official gem as far as I know. There is one here but the last update was on Jan, 2014. Current master branch is far ahead of this release. So, clone the Lotus project in order to install from source.

1
git clone https://github.com/lotus/lotus.git

We need bundler to manage gem dependancy. Let’s create a Gemfile.

1
bundle init

Edit your Gemfile. Change <your-path-to-lotus-repo> to the directory where you clone Lotus repo.

1
2
source "https://rubygems.org"
gem 'lotusrb', :path => <your-path-to-lotus-repo>

Then install gems.

1
bundle install --path vendor/

Now, we can start writing our application which is just one file. Save below codes as config.ru.

config.ru

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
require 'lotus'

module OneFile
  class Application < Lotus::Application
    configure do
      routes do
        get '/', to: 'home#index'
      end
    end
    load!
  end

  module Controllers
    module Home
      include OneFile::Controller

      action 'Index' do
        def call(params)
        end
      end
    end
  end

  module Views
    module Home
      class Index
        include OneFile::View

        def render
          "Hello, Lotus"
        end
      end
    end
  end
end

run OneFile::Application.new

You can run the app with rackup command.

1
bundle exec lotus server

Successfully run? Then, access http://localhost:2300 from your browser. You should see Hello, Lotus.

Let me explain what is doing.

First, you will notice that classes inside Controllers and Views modules not using inheritance. One important philosophy of Lotus is this:include a module and implement a minimal interface. This philosophy encourages developers to use only what you need with mixin.

Now let’s look at Application class. In our application, the class only configures routes. We use get method to configure a route for http GET / method that uses Home::Index controller. Here we only configure get http method, but you can configure other methods easily such as these:

1
2
3
4
5
6
7
8
routes do
  post   '/books',             to: 'book#create'
  put    '/books/:id',         to: 'book#update'
  delete '/books/:id',         to: 'book#destroy'

  # You can also define one liner response
  get    '/ping',              to: ->(env) {[200, {}, ['pong']]}
end

Next, let’s look at Controllers. We are not doing anything but defining action. What is action? action is the HTTP endpoint where you can handle incoming request and creating response. This is also the place where you can implement your business logic. I think it is safe to think that the responsibility of Lotus action is very similar to Rails controller. We define Index action so that we can use it from our router code that we looked at previously.

Last thing to look at is Views. The responsibility of the class is not the same as the Rails view class. In Rails, you write codes that is actually rendered by browser (if html format) in view. This is done by Template in Lotus which I don’t cover in this post. In Lotus, the responsibility of view is more like of presenter which does not come with Rails by default (you can use gems such as Draper to implement presetation layer in Rails, too.) What presenter does is receiving data from controller and abstracts them to template layer. In this way, your template layer gets clean and can focus on redning content.

Let’s go back to our code. Here we define render method and simply print Hello, Lotus message.

This is neither interesting nor useful. We will make view to interact with controller by via data.

Let’s modify your controller.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module Controllers
  module Home
    include OneFile::Controller
    action 'Index' do

      expose :time

      def call(params)
        @time = Time.now
      end
    end

  end
end

Now, we see two new things expose and call.

To pass data from controller to view, you need to manually expose what you want to pass. Again, here you see Lotus philosophy: only use what you need.

call is the entry point of http request. As I mentioned earlier, you can write business logic as well as response handling codes here.

Let’s modify your view to get data from the controller.

1
2
3
4
5
6
7
8
9
10
11
module Views
  module Home
    class Index
      include OneFile::View

      def render
        "Current time: #{time}"
      end
    end
  end
end

Since our controller exposes @time, you can access the data via time from your view. Now, restart your Rack process and access from your browser. Now you should see something like this: Current time: 2014-09-11 23:18:30 +0900

Wrap up

Did you see it is quite easy to write Lotus application?

Ok, I can hear your voice: this example is too simple. I want to see real Lotus application.

Yes, let me do that in the next post. I thought I can do that in the same post, but writing this takes more time than I thought…

Next post will be something like this: Creating Full Stack Web Application with Lotus

Comments

« CRIUを使ってDockerコンテナの停止/再開に挑戦 Ruby LotusでWeb Appを作ってみる »