kemal/README.md

186 lines
4.5 KiB
Markdown
Raw Normal View History

2015-10-28 18:56:39 +00:00
<img src="https://avatars3.githubusercontent.com/u/15321198?v=3&s=200" width="100" height="100" />
2015-11-22 09:41:21 +00:00
# Kemal [![Build Status](https://travis-ci.org/sdogruyol/kemal.svg?branch=master)](https://travis-ci.org/sdogruyol/kemal)
2015-06-01 21:06:26 +00:00
2015-12-05 21:14:12 +00:00
[![Join the chat at https://gitter.im/sdogruyol/kemal](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sdogruyol/kemal?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2015-10-27 05:08:15 +00:00
Lightning Fast, Super Simple web framework for [Crystal](http://www.crystal-lang.org).
Inspired by [Sinatra](http://www.sinatrarb.com/)
2015-10-23 18:44:41 +00:00
2015-10-23 18:50:19 +00:00
Kemal is under heavy development and currently supports Crystal 0.9.0.
2015-10-23 19:43:33 +00:00
# Super Simple <3
```ruby
2015-10-24 13:48:47 +00:00
require "kemal"
2015-10-23 19:43:33 +00:00
get "/" do
"Hello World!"
end
```
2015-10-24 16:20:49 +00:00
Build and run!
```
crystal build --release src/kemal_sample.cr
./kemal_sample
```
2015-10-23 19:43:33 +00:00
Go to *http://localhost:3000*
2015-10-29 09:20:32 +00:00
Check [samples](https://github.com/kemalcr/kemal/tree/master/samples) for more.
2015-10-24 13:50:26 +00:00
2015-11-09 18:57:54 +00:00
# Super Fast <3
Numbers speak louder than words.
| Framework | Request Per Second | Avg. Response Time |
| :------------ |:---------------:| -----:|
2015-11-19 18:20:51 +00:00
| Kemal (Production) | 64986 | 170μs |
2015-11-09 18:57:54 +00:00
| Sinatra (Thin) | 2274 | 43.82ms |
2015-11-17 19:53:33 +00:00
These results were achieved with ```wrk``` on a Macbook Pro Late 2013. (**2Ghz i7 8GB Ram OS X Yosemite**)
2015-10-23 18:50:19 +00:00
# Installation
2015-12-02 19:02:39 +00:00
Kemal supports Crystal 0.9.0 and up.
You can add Kemal to your project by adding it to ```shard.yml```
2015-10-23 18:50:19 +00:00
```yml
2015-12-02 19:02:39 +00:00
name: your-app
2015-10-23 18:50:19 +00:00
dependencies:
kemal:
2015-11-21 10:29:35 +00:00
github: sdogruyol/kemal
2015-10-23 18:50:19 +00:00
branch: master
```
2015-06-01 21:06:26 +00:00
2015-10-29 09:41:00 +00:00
## Routes
2015-06-01 21:06:26 +00:00
2015-10-29 09:41:00 +00:00
In Kemal, a route is an HTTP method paired with a URL-matching pattern. Each route is associated with a block:
```ruby
2015-10-29 09:42:54 +00:00
get "/" do
2015-10-29 09:41:00 +00:00
.. show something ..
end
2015-10-29 09:42:54 +00:00
post "/" do
2015-10-29 09:41:00 +00:00
.. create something ..
end
2015-10-29 09:42:54 +00:00
put "/" do
2015-10-29 09:41:00 +00:00
.. replace something ..
end
2015-10-29 09:42:54 +00:00
patch "/" do
2015-10-29 09:41:00 +00:00
.. modify something ..
end
2015-10-29 09:42:54 +00:00
delete "/" do
2015-10-29 09:41:00 +00:00
.. annihilate something ..
end
```
2015-10-30 20:40:37 +00:00
## Environment
2015-10-29 09:41:00 +00:00
2015-10-30 20:40:37 +00:00
Accessing the environment (query params, body, content_type, headers, status_code) is super easy. You can use the environment returned from the block:
2015-10-29 09:41:00 +00:00
```ruby
# Matches /hello/kemal
2015-10-29 09:49:58 +00:00
get "/hello/:name" do |env|
name = env.params["name"]
2015-10-29 09:41:00 +00:00
"Hello back to #{name}"
end
# Matches /resize?width=200&height=200
2015-10-29 09:49:58 +00:00
get "/resize" do |env|
width = env.params["width"]
height = env.params["height"]
2015-10-29 09:41:00 +00:00
end
2015-11-06 18:49:08 +00:00
# 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
2015-10-29 09:41:00 +00:00
# Set the content as application/json and return JSON
2015-10-29 09:49:58 +00:00
get "/user.json" do |env|
2015-10-29 09:42:54 +00:00
kemal = {name: "Kemal", language: "Crystal"}
2015-10-30 20:40:37 +00:00
env.content_type = "application/json"
2015-10-29 09:41:00 +00:00
kemal.to_json
end
2015-10-31 08:03:55 +00:00
2015-10-30 20:40:37 +00:00
# Add headers to your response
get "/headers" do |env|
env.add_header "Accept-Language", "tr"
env.add_header "Authorization", "Token 12345"
end
2015-10-29 09:41:00 +00:00
```
2015-10-23 19:51:39 +00:00
### Browser Redirect
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.
```ruby
# 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._
2015-11-13 19:23:05 +00:00
## Middlewares
You can create your own middlewares by inheriting from ```HTTP::Handler```
```crystal
class CustomHandler < HTTP::Handler
def call(request)
puts "Doing some custom stuff here"
call_next request
end
end
Kemal.config.add_handler CustomHandler.new
```
### Views
You can use ERB-like built-in **ECR** views to render files.
```crystal
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.
```erb
Hello <%= env.params["name"] %>
```
2015-11-01 08:40:49 +00:00
## Static Files
2015-11-02 19:43:42 +00:00
Kemal has built-in support for serving your static files. You need to put your static files under your ```/public``` directory.
2015-11-01 08:40:49 +00:00
2015-11-02 19:43:42 +00:00
E.g: A static file like ```/public/index.html``` will be served with the matching route ```/index.html```.
2015-11-01 08:40:49 +00:00
## Production / Development Mode
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```
2015-10-23 19:51:39 +00:00
## Thanks
Thanks to Manas for their awesome work on [Frank](https://github.com/manastech/frank).