Lightning Fast, Super Simple web framework for Crystal. Inspired by Sinatra
Kemal is under heavy development and currently supports Crystal 0.9.0.
require "kemal"
get "/" do
"Hello World!"
end
Build and run!
crystal build --release src/kemal_sample.cr
./kemal_sample
Go to http://localhost:3000
Check samples for more.
Numbers speak louder than words.
Framework | Request Per Second | Avg. Response Time |
---|---|---|
Kemal (Production) | 64986 | 170μs |
Sinatra (Thin) | 2274 | 43.82ms |
These results were achieved with wrk
on a Macbook Pro Late 2013. (2Ghz i7 8GB Ram OS X Yosemite)
Kemal supports Crystal 0.9.0 and up.
You can add Kemal to your project by adding it to shard.yml
name: your-app
dependencies:
kemal:
github: sdogruyol/kemal
branch: master
In Kemal, a route is an HTTP method paired with a URL-matching pattern. Each route is associated with a block:
get "/" do
.. show something ..
end
post "/" do
.. create something ..
end
put "/" do
.. replace something ..
end
patch "/" do
.. modify something ..
end
delete "/" do
.. annihilate something ..
end
Accessing the environment (query params, body, content_type, headers, status_code) is super easy. You can use the environment returned from the block:
# Matches /hello/kemal
get "/hello/:name" do |env|
name = env.params["name"]
"Hello back to #{name}"
end
# Matches /resize?width=200&height=200
get "/resize" do |env|
width = env.params["width"]
height = env.params["height"]
end
# Easily access JSON payload from the params.
# The request content type needs to be application/json
# The payload
# {"name": "Serdar", "likes": ["Ruby", "Crystal"]}
post "/json_params" do |env|
name = env.params["name"] as String
likes = env.params["likes"] as Array
"#{name} likes #{likes.each.join(',')}"
end
# Set the content as application/json and return JSON
get "/user.json" do |env|
kemal = {name: "Kemal", language: "Crystal"}
env.content_type = "application/json"
kemal.to_json
end
# Add headers to your response
get "/headers" do |env|
env.add_header "Accept-Language", "tr"
env.add_header "Authorization", "Token 12345"
end
Just like other things in kemal
, browser redirection is super simple as well. Use environment
variable in defined route's corresponding block and call redirect
on it.
# Redirect browser
get "/logout" do |env|
# important stuff like clearing session etc.
redirect "/login" # redirect to /login page
end
Make sure to receive env
as param in defined route's block or you might end-up having compile-time errors.
You can create your own middlewares by inheriting from HTTP::Handler
class CustomHandler < HTTP::Handler
def call(request)
puts "Doing some custom stuff here"
call_next request
end
end
Kemal.config.add_handler CustomHandler.new
You can use ERB-like built-in ECR views to render files.
get '/:name' do
render "views/hello.ecr"
end
And you should have an hello.ecr
view. It will have the same context as the method.
Hello <%= env.params["name"] %>
Kemal has built-in support for serving your static files. You need to put your static files under your /public
directory.
E.g: A static file like /public/index.html
will be served with the matching route /index.html
.
By default Kemal starts in development
mode and logs to STDOUT.
You can use production
mode to redirect the output to a file. By default Kemal logs the output to kemal.log
.
You can start Kemal in production mode by:
./your_app -e production
Thanks to Manas for their awesome work on Frank.