No description
Find a file
Imran Latif d25a611fbd Implemented HTTP HEAD method.
First I tried implementing this solution in such a way that it
explicitly clears body and set `Content-Length` header to body's size.
But for some reason, if I call the URL from cURL then `Content-Length`
header was blank which defeats the very purpose of `HEAD` requests.

I then later anticipated that since `HEAD` would be by-default
implemented by `HTTP::Server` module, there is no need to explicit
clears body and setting `Content-Length` but the way we have written
our previous specs were returning body as well. We could have used some
TestServer kind of thing but if we go to that route we explicitly need
to test non-existent route which I thought would create some
inconsistency among specs.

Crystal has clearly written specs for HEAD requests to make sure body
is not read for them. See
https://github.com/manastech/crystal/commit/acd0b6afb5af438a30529c36b11b
e7954336f23f. I decided to write simple specs which are easy to
maintain in long-run.

We are adding identical HEAD route for every GET route which will make
HEAD requests available for all defined GET requests.

https://github.com/sdogruyol/kemal/issues/19

Added comment for code line which is adding HEAD routes for defined GET routes.
2015-12-04 19:35:14 +05:00
samples Fix JSON API sample. 2015-11-09 16:20:04 -08:00
spec Implemented HTTP HEAD method. 2015-12-04 19:35:14 +05:00
src Implemented HTTP HEAD method. 2015-12-04 19:35:14 +05:00
.gitignore Updated logger to be more robust 2015-11-18 22:45:49 +02:00
.travis.yml Add 404 2015-11-27 22:45:13 +02:00
Guardfile Added Guardfile 2015-10-28 17:37:51 +02:00
README.md Clearer installation instructions 2015-12-02 21:02:39 +02:00
shard.yml Update shard.yml 2015-11-21 12:29:10 +02:00

# Kemal [![Build Status](https://travis-ci.org/sdogruyol/kemal.svg?branch=master)](https://travis-ci.org/sdogruyol/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

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

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.

Production / Development Mode

By default Kemal starts in developmentmode 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

Thanks to Manas for their awesome work on Frank.