diff --git a/README.md b/README.md index 2022c03..bf80a37 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,11 @@ end Build and run! ``` -crystal build --release src/kemal_sample.cr -./kemal_sample +crystal run src/kemal_sample.cr ``` Go to *http://localhost:3000* -Check [samples](https://github.com/kemalcr/kemal/tree/master/samples) for more. +Check [samples](https://github.com/sdogruyol/kemal/tree/master/samples) for more. # Super Fast <3 @@ -40,145 +39,15 @@ Numbers speak louder than words. These results were achieved with ```wrk``` on a Macbook Pro Late 2013. (**2Ghz i7 8GB Ram OS X Yosemite**) -# Installation +# Features -Kemal supports Crystal 0.9.0 and up. -You can add Kemal to your project by adding it to ```shard.yml``` - -```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: - -```ruby - 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: - -```ruby - # 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 -``` - -### 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._ - -## 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"] %> -``` - -## 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 ```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``` +- Support all REST verbs +- Websocket support +- Request/Response context, easy parameter handling +- Middlewares +- Built-in JSON support +- Built-in static file serving +- Built-in view templating via ecr ## Thanks diff --git a/docs/README.md b/docs/README.md index db787ac..a76365f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,11 +22,12 @@ Kemal means *Mature, grown up* in Turkish. ## How to start? - - [Getting Started Tutorial](./tutorial.md) + - [Getting Started Tutorial](./getting_started.md) + - [Restful Web Services](./rest.md) + - [Websockets](./websockets.md) - [Using Dynamic Views](./views.md) - [HTTP Requests and Responses](./http-requests.md) - - [Uploading Files](./upload.md) - [Serving Static Files](./statics.md) - [Serving JSON API](./json.md) - - [Restful Web Services](./rest.md) + - [Middlewares](./middlewares.md) - [How to connect to Database](./database.md) diff --git a/docs/tutorial.md b/docs/getting_started.md similarity index 100% rename from docs/tutorial.md rename to docs/getting_started.md diff --git a/docs/http-requests.md b/docs/http-requests.md index f424a97..1e21e36 100644 --- a/docs/http-requests.md +++ b/docs/http-requests.md @@ -1,9 +1,9 @@ -# Handling HTTP Request/Response +# HTTP Request / Response Lifecycle -You should use `env` variable to handle HTTP Request/Response. For both `get` and `post` (and others) methods, you should use the yielded `env` object. +Accessing the HTTP request/response environment (query params, body, content_type, headers, status_code) is super easy. You can use the environment returned from the block: ```ruby -# Matches /hello/kemal + # Matches /hello/kemal get "/hello/:name" do |env| name = env.params["name"] "Hello back to #{name}" @@ -37,4 +37,3 @@ You should use `env` variable to handle HTTP Request/Response. For both `get` an env.add_header "Accept-Language", "tr" env.add_header "Authorization", "Token 12345" end -``` diff --git a/docs/middlewares.md b/docs/middlewares.md new file mode 100644 index 0000000..048556e --- /dev/null +++ b/docs/middlewares.md @@ -0,0 +1,14 @@ +# 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 +``` diff --git a/docs/static_files.md b/docs/static_files.md new file mode 100644 index 0000000..d4d1b2c --- /dev/null +++ b/docs/static_files.md @@ -0,0 +1,15 @@ +## 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 ```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``` diff --git a/docs/utilities.md b/docs/utilities.md new file mode 100644 index 0000000..acb72d4 --- /dev/null +++ b/docs/utilities.md @@ -0,0 +1,11 @@ +# 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._ diff --git a/docs/views.md b/docs/views.md index c91125d..429c66d 100644 --- a/docs/views.md +++ b/docs/views.md @@ -1,29 +1,15 @@ # Views -You can use ECR to build views. Kemal serves a `render` macro to use Crystal's built-in `ECR` -library. - -## Embedding View File +You can use ERB-like built-in **ECR** views to render files. ```crystal -get '/' do |env| - your_name = "Kemal" +get '/:name' do render "views/hello.ecr" end ``` -## Writing Views +And you should have an `hello.ecr` view. It will have the same context as the method. -ECR is pretty similar ERB(from Ruby). As you can see you can easily access the block variables in your view. In this -example `your_name` is available for use in the view. - -``` -src/ - views/ - hello.ecr -``` - -Write `hello.ecr` ```erb -Hello <%= your_name %> +Hello <%= env.params["name"] %> ```