[erlang-questions] Web server structure: Rack
Dmitrii Dimandt
dmitriid@REDACTED
Sun Jan 10 14:19:03 CET 2010
It's actually http://github.com/skarab/ewgi now
> Max,
>
> Have you seen ewgi? It's similar to Rack and WSGI. http://code.google.com/p/ewgi/
>
> Sean
>
> On 1/9/10 12:50 PM, Max Lapshin wrote:
>> Hi, I've promised to talk about better structure of web stack. I want
>> to tell about Ruby on Rails experience.
>> Basically Rails application is built according to MVC paradigm: Model,
>> View, Controller. Perhaps everyone here have
>> heard about it.
>>
>> Most interesting here will be speak about structure of View and
>> Controller layers. Web application violates pure MVC structure,
>> because in web application controller must present object of Model
>> layer to template engine.
>>
>> So, after years of development, Rails came to the concept of Rack
>> infrastructure.
>>
>> After parsing HTTP headers request is represented as hash table with
>> http headers. Then this request is passed
>> through configured chain of filters, that is ended with some handler.
>>
>> Let's look at an example config:
>>
>> use ActionController::Failsafe # this is global exception handler,
>> that captures all errors and show 500 in
>> use ActionController::PageCache # tries to find whole page cached
>> map "/advert" do # enables mapping all requests to
>> /advert to special handler.
>> run FastAdvertHandler
>> end
>>
>> map "/" do # all other requests are
>> moving to this section
>> use ActionController::Session::CookieStore, , {:secret=>"some_key",
>> :session_key=>"_rails_session"} # loads session from cookie
>> use ActionController::ParamsParser # decode all params and
>> parses query string
>> use Rack::Head # discard body is HTTP HEAD
>> use Rails::Router # checkout what
>> controller and action will handle request
>> run Rails::Dispatcher
>> end
>>
>>
>> Each filter can store required information in mutable request, which
>> is hash. Lets look at code of such filter:
>>
>>
>> module Rack
>> module Session
>> class Cookie
>> def initialize(app, options = {})
>> @app = app
>> @key = options[:key] || "rack.session" # Variables,
>> starting from @ in ruby are just object instance variables
>> @secret = options[:secret]
>> end
>>
>> def call(env) # this method is by interface, requred method
>> of each handler
>> load_session(env) # this method take
>> status, headers, body = @app.call(env) # this line is
>> by interface required part of calling further request processing.
>> commit_session(env, status, headers, body)
>> end
>>
>> def load_session(env)
>> env["rack.session"] = load_session_from_cookie(env[@key]) #
>> here we take cookie, named the same as our key and decode it
>> end
>>
>> def commit_session
>> ... # this method packs session to cookie back.
>> end
>> end
>> end
>> end
>>
>>
>> It is very important, that each filter can control, when to call
>> subfilters up to last request handler.
>> Second important thing, that there is defined convention, how to name
>> request keys: env["rack.session"] is for session,
>> env["request.error"] is for backtrace of request exceptions.
>>
>> Let's look, how would it be possible to repeat this structure in Erlang:
>>
>>
>> -module(rack_server).
>> -export([rack_config/0]).
>>
>> rack_config() ->
>> [
>> controller_failsafe, % name of module
>> controller_cookiestore:new("secretstring", "_example_session"),
>> ...
>> ].
>>
>> Here is sketch:
>> http://github.com/maxlapshin/erack/blob/master/src/example_server.erl
>>
>> so can look controller_failsafe module:
>>
>> -module(controller_failsafe).
>> -export([call/2]).
>> -behaviour(rack_handler).
>>
>> call(App, Request) ->
>> try App:call(Request) of
>> Reply -> Reply
>> catch
>> error:notfound -> [404, [{"Content-Type", "text/plain"}], "404 Not found"];
>> _:_ -> [500, [{"Content-Type", "text/plain"}], "500 Server
>> error"++lists:flatten(io_lib:format("~n~p~n",
>> [erlang:get_stacktrace()]))]
>> end.
>>
>>
>>
>> Concept of Rack handlers became a glue idea for most ruby frameworks,
>> making useless many of them, because they appeared to be just a one
>> rack config with some set of handlers =)
>>
>> What do I want? To discuss this api and promote its implementation in
>> erlang web servers. Also it would be great to extract implementation
>> of the whole controller layer
>> out of Zotonic CMS into reusable components. I'm willing to reuse its
>> code in my applications, but it is impossible, because business logic
>> and infrastructure logic are in one repository.
>>
>> ________________________________________________________________
>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>> erlang-questions (at) erlang.org
>>
>>
>>
>
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
More information about the erlang-questions
mailing list