Find a file
2015-11-20 23:12:12 +02:00
samples Fix JSON API sample. 2015-11-09 16:20:04 -08:00
spec More logger specs 2015-11-20 23:07:10 +02:00
src Added config env to startup message 2015-11-20 23:12:12 +02:00
.gitignore Updated logger to be more robust 2015-11-18 22:45:49 +02:00
.travis.yml Added travis.yml 2015-10-31 09:59:44 +02:00
Guardfile Added Guardfile 2015-10-28 17:37:51 +02:00
README.md Updated benchmark 2015-11-19 20:20:51 +02:00
shard.yml Bump version 2015-11-06 20:35:36 +02:00

# Kemal [![Build Status](https://travis-ci.org/kemalcr/kemal.svg?branch=master)](https://travis-ci.org/kemalcr/kemal)

Lightning Fast, Super Simple web framework for Crystal. Inspired by Sinatra

Kemal is under heavy development and currently supports Crystal 0.9.0.

Super Simple <3

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.

Super Fast <3

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)

Installation

Add it to your shard.yml

dependencies:
  kemal:
    github: kemalcr/kemal
    branch: master

Routes

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  

Environment

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

Middlewares

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

Static Files

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.

Thanks

Thanks to Manas for their awesome work on Frank.