[erlang-questions] Web server structure: Rack
Sean Cribbs
seancribbs@REDACTED
Sat Jan 9 19:23:34 CET 2010
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
>
>
>
More information about the erlang-questions
mailing list