Skip to content

mtrense/mojito

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mojito – Next level Ruby webframework

Mojito is a lean and simple webframework.

As the name implies mojito derives from cuba (https://github.com/soveran/cuba). Many thanks to Michel and his cuba project for giving me some major insights on web-application-simplicity! See also https://github.com/mtrense/mojito-examples for more examples.

Installing

$ gem install mojito

Your first application

The easiest way to start with mojito is to use a plain config.ru script to develop and configure your application.

$ cat config.ru
require 'mojito'

class FirstApp
	include Mojito
	controller :runtime
	rendering :all
	
	on GET(), PATH('/hello/:name') do |name|
		write "Hello #{name}! How are you?"
		content_type :plain
		ok!
	end
end

run FirstApp

This installs a handler for GET requests to a path of /hello/ followed by a name (actually this notation catches everything but a slash ‘/’). You can start this application by running rackup from the same directory:

$ rackup

This starts a http-server on port 9292. Now try to call your handler with curl:

$ curl http://localhost:9292/hello/Fred
Hello Fred! How are you?

Controllers

Controllers are the common building blocks of Mojito Applications. For each successful request at least one controller is instantiated. The call to controller :runtime actually defines the calling class as runtime controller and includes the corresponding module – Mojito::Controllers::Runtime in this case. For a specific class one can choose from many controller types, each of which is specialized to a specific use-case.

Controller classes are actually Rack-Applications, so they must provide a (class-)method call(env). The common sequence of processing a request includes:

  • call(env) is called from the surrounding application/the framework
  • a new instance of the controller-class is instantiated and configured with the given environment
  • a kind of dispatch method (__dispatch for build-in controllers) is called to do the actual work

This ensures that the controller instance which handles a specific request is used solely for that request, so that any instance variables created during request-processing stay request-local. At the same time this keeps application stacking and nesting as simple as call-ing the next application.

Structure of a real-world application

This is not up-to-date

The above call to Mojito.application actually created a class and included most of Mojitos foundation methods, so that you could start writing your application code without wondering what features you want to include in your application. As a tribute to simplicity (one of the most important I think), another helper method Mojito.base_application can be used to create a blank application class, which only includes modules that are strictly necessary. Instead of using those methods you can also write out all of the generated classes code (here Mojito is included, which in turn includes Mojito::Base, the basic module which is used by Mojito.base_application):

class FirstApp
	include Mojito
	routes do
		on GET(), PATH('/hello/:name') do |name|
			...
		end
	end
end

which is not only perfectly legal but also favoured, when you need any special behaviour on your application class.

Although you can actually use any structure you want (including a single-file application), some of them are more useful than others. My preferred way of developing Mojito applications is to reuse most of the concepts found in product development with rubygems and git.

Behind the scenes

Understanding how Mojito dispatches requests and selects handlers, which in turn use common functionality to create the response is vital to an efficient use of Mojito as web application framework. First of all Mojito applications (classes which include Mojito::Base or Mojito) are simply Ruby classes, which are instantiated with the Rack-environment hash for each request. This is automatically triggered by a rack-enabled webserver through the call of run ApplicationClass, which tells rack to call call(env) on that class. The Mojito implementation will then instantiate the Application (the instance is called a controller from now on) and call dispatch on that controller. The dispatch method then executes any block given to the routes-method in the class definition. As in Cuba the routes-definition is executed once for each request.

Matching

A matcher is simply a Proc, instantiated with matcher-specific configuration, which returns whether or not a given request matches its criteria. The request-method matcher for example is implemented as follows:

	def METHOD(method)
	proc { request.request_method == method.to_s.upcase }
end

This method configures a Proc to return true when the requests method matches the given parameter. The returned Proc is evaluated in the context of the current controller. This is also where the request method comes from. Like request, a matcher can access any method from the controller, within which it is executed. The naming convention is to name all matchers uppercase.

Rendering

Helpers

Deployment/Hosting

tbd

Writing extensions

tbd

Contributing to mojito

  • Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet.
  • Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it.
  • Fork the project.
  • Start a feature/bugfix branch.
  • Commit and push until you are happy with your contribution.
  • Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright

Copyright © 2012 Max Trense. See LICENSE.txt for further details.

About

Mojito is a lean and simple webframework.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages