Skip to content

Instantly share code, notes, and snippets.

@janko
Created May 27, 2015 23:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save janko/46f93b684daf15ad9312 to your computer and use it in GitHub Desktop.
Save janko/46f93b684daf15ad9312 to your computer and use it in GitHub Desktop.
The Roda Ruby framework (my presentation on our local Ruby meetups)

Roda

  • Web framework (on top of Rack)

  • Forked from Cuba

  • Core + Plugins

    • Core: 440 LOC
    • Total: 3200 LOC
  • In my opinion the best framework for JSON APIs

    • (Rails, Sinatra, Grape, Cuba, Lotus, Webmachine, Pliny)
require "roda"
Roda.route { "" }
Roda.app # Rack application
require "roda"
class App < Roda
# GET /hello
route do |r|
r.get "hello" do
"Hello world!"
end
end
end
require "roda"
class App < Roda
# GET /foo/bar/baz
route do |r|
# "/foo/bar/baz"
r.on "foo" do
# "/bar/baz"
r.on "bar" do
# "/baz"
r.get "baz" do
# ""
"request matched"
end
end
end
r.get "foo/bar/baz" do
"request matched"
end
end
end
require 'sinatra/base'
class App < Sinatra::Base
get '/' do
erb :index
end
get '/artist/:id' do
@artist = Artist[params[:id]]
check_access(@artist)
erb :artist
end
post '/artist/:id' do
@artist = Artist[params[:id]]
check_access(@artist)
@artist.update(params[:artist])
redirect(request.path_info)
end
delete '/artist/:id' do
@artist = Artist[params[:id]]
check_access(@artist)
@artist.destory
redirect '/'
end
end
require 'roda'
class App < Roda
plugin :render
plugin :all_verbs
route do |r|
r.root do
view :index
end
r.on 'artists' do
r.is ':id' do |artist_id|
@artist = Artist[artist_id]
check_access(@artist)
r.get do
view :artist
end
r.post do
@artist.update(r['artist'])
r.redirect(request.path_info)
end
r.delete do
@artist.destroy
r.redirect '/'
end
end
end
end
end
require "roda"
class App < Roda
route do |r|
r.get "quizzes" do
if current_user
@quizzes = current_user.quizzes
else
@quizzes = Quiz.search(params[:q])
end
end
end
end
require "roda"
class App < Roda
plugin :header_matchers
route do |r|
r.get "quizzes", header: "Authorization" do
@quizzes = current_user.quizzes
end
r.get "quizzes" do
@quizzes = Quiz.search(params[:q])
end
end
end
require "roda"
class App < Roda
plugin :path_matchers
route do |r|
r.on "quizzes/:id" do
r.get extension: "json" do
# ...
end
r.get extension: "pdf" do
# ...
end
end
end
end
require "roda"
class App < Roda
# Legacy routes ("/foo", "/bar")
route do |r|
r.get "foo", "bar" do
# ...
end
end
end
require "rails"
class ArticlesController < ApplicationController
def show
render json: Article.find(params[:id])
end
def update
render json: Article.update(params[:id], params[:article])
end
def delete
render json: Article.destroy(params[:id])
end
end
require "roda"
class App < Roda
plugin :json, serializer: Serializer
route do |r|
r.is "article/:id" do |id|
r.get do
Article.find(id)
end
r.put do
Article.update(id, params[:article])
end
r.delete do
Article.delete(id)
end
end
end
end
class Serializer
def self.call(object)
case object
when Hash, Array
object.to_json
when Sequel::Model, Sequel::Dataset
# custom serialization
end
end
end
  • Simplicity

    • understanding how a framework works gives your power
  • Extensibility (50+ plugins)

    • JSON
    • HTTP caching
    • Streaming
    • ...
  • Performance

    • empty Rails request is 10x slower than Roda's
    • around 2x faster tests
  • Dynamic routing resolution

    • revolutionizes the way you write your controller code
    • Your routes are right there with their handlers (like Sinatra and Grape)
  • Great for JSON APIs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment