Roda suport get
and post
verbs initially
class App < Roda
route do |r|
r.get do # GET
r.on "a" do # GET /a branch
r.on "b" do # GET /a/b branch
r.is "c" do end # GET /a/b/c request
r.is "d" do end # GET /a/b/d request
end
end
end
r.post do # POST
r.on "a" do # POST /a branch
r.on "b" do # POST /a/b branch
r.is "c" do end # POST /a/b/c request
r.is "e" do end # POST /a/b/e request
end
end
end
end
end
For delete
, put
and patch
, we must use all_verbs
plugin
class App < Roda
plugin :all_verbs
route do |r|
route do |r|
r.delete do
# Handle DELETE
end
r.put do
# Handle PUT
end
r.patch do
# Handle PATCH
end
end
end
end
Getting values from url
class App < Roda
# GET /post/2011/02/16/hello
r.get "post", Integer, Integer, Integer, String do |year, month, day, slug|
"#{year}-#{month}-#{day} #{slug}" #=> "2011-02-16 hello"
end
end
More info:
- "The Routing Tree" section on Roda README
- "Matchers" section on Roda README
- (all_verbs plugin) https://roda.jeremyevans.net/rdoc/classes/Roda/RodaPlugins/AllVerbs.html
- "Basic routing" from "Mastering Roda" book
- "Match methods" from "Mastering Roda" book
Create a directory for views named views
in the root of your project
$ mkdir views
Create a layout file inside this directory
$ touch views/layout.erb
<%= yield %>
Create the view file
$ touch views/foo/index.erb
<h1> Hello, <%= @name %> </h1>
Age: <%= age %>
Add :render
plugin and view 'foo/index'
class App < Roda
plugin :render # import render
route do |r|
@name = 'Henrique' # will be available in the erb file
r.root do
view 'foo/index', locals: { age: 26 } # this maps to views/food/index.erb with layout
end
r.get 'without-layout' do
render 'foo/index', locals: { age: 26 } # this maps to views/food/index.erb without layout
end
end
end
More info:
- 'Rendering' section on Roda README.md
- (render plugin) https://roda.jeremyevans.net/rdoc/classes/Roda/RodaPlugins/Render.html
- "Layouts" from "Mastering Roda" book
- "Render" from "Mastering Roda" book
class App < Roda
plugin :public # Will serve any file / folder in <your_app_root>/public
route do |r|
r.public
end
end
More info:
class App < Roda
# some_file.scss is the scss root, the same for some_file.js for javascript
# it will find assets/css/some_file.scss and assets/js/some_file.js
plugin :assets, css: 'some_file.scss', js: 'some_file.js' # Add this plugin
route do |r|
r.assets # Add this call
r.get { |r| view 'index' }
end
end
Create the layout file:
$ mkdir views && touch views/layout.erb
<html>
<head>
# The link to files
<%= assets(:css) %>
<%= assets(:js) %>
</head>
<body>
<%= yield %>
</body>
</html>
Create the view file:
$ touch views/index.erb
<h1> Hello </h1>
Create some scss files:
$ mkdir assets/css && touch assets/css/some_file.scss
@import 'global.scss';
$ touch assets/css/_global.scss
body {
background-color: blue;
}
Create the js file:
$ mkdir assets/js && touch assets/js/some_file.js
console.log("hello")
More info:
class App < Roda
plugin :json # import json
route do |r|
r.root do
[{
name: 'Banana',
nutrients: [
{
name: 'B vitamin',
quantity: 3,
quantity_unit: 'mg'
}
]
}] # automatic conversion to json
end
end
end
More info:
class App < Roda
route do |r|
r.root do
response.status = 201 # Set status in global response object
"" # return something
end
end
end
More info:
class App < Roda
plugin :halt # load the halt plugin
route do |r|
r.root do
r.halt(403)
end
r.get "example2" do
r.halt('body')
end
r.get "example3" do
r.halt(403, 'body')
end
r.get "example4" do
r.halt(403, {'Content-Type'=>'text/csv'}, 'body')
end
r.get "example5" do
r.halt([403, {'Content-Type'=>'text/csv'}, ['body']])
end
end
end
More info:
Use rack-cors
gem:
gem 'rack-cors' # Gemfile
in config.ru
:
require "rack/cors"
require_relative "app" # require roda app
use Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :patch, :put]
end
end
run App.freeze.app
More info:
Use rerun
gem:
$ gem install rerun
and then:
$ rerun 'rackup'
More info:
Run Roda with this command
rackup --host 0.0.0.0 --port 9292
and then, access your IP address in port 9292
"Cross Site Scripting (XSS)" section on Roda README
routes/foo.rb
module Routes
class Foo < Roda
route do |r|
r.get do
"hello foo"
end
end
end
end
routes/bar.rb
module Routes
class Bar < Roda
route do |r|
r.get do
"hello bar"
end
end
end
end
config.ru
require "roda"
Dir['routes/*.rb'].each { |f| require_relative f }
class App < Roda
plugin :multi_run # Allow to group many "r.run" in one call
run 'foo', Routes::Foo
run 'bar', Routes::Bar
# Same as
# route do |r|
# r.multi_run
# end
route(&:multi_run)
end
run App.freeze.app
routes/foo.rb
module Routes
module Foo
def self.included(app)
app.class_eval do
route('foo') do |r|
r.get do
"hello foo, #{@shared_value}"
end
end
end
end
end
end
routes/bar.rb
module Routes
module Bar
def self.included(app)
app.class_eval do
route('bar') do |r|
r.get do
"hello bar, #{@shared_value}"
end
end
end
end
end
end
config.ru
require "roda"
Dir['routes/*.rb'].each { |f| require_relative f }
class App < Roda
plugin :multi_route
include Routes::Foo
include Routes::Bar
# route(&:multi_route)
route do |r|
# with this option, keep in mind that all routes will share the same class scope even in separated files
# functions defined outside the 'route' block in routes modules may be dangerous
@shared_value = 'keep focus'
r.multi_route
end
end
run App.freeze.app
More info:
- "Conventions" section on Roda doc
- "Composition" section on Roda README
- (multi_route plugin) https://roda.jeremyevans.net/rdoc/classes/Roda/RodaPlugins/MultiRoute.html
Install and use Shrine (https://shrinerb.com/)
Help us grow this Roda cookbook, open a PR with your contribution!