Dreisam – how it works


Dreisam is an MVC web application framework inspired by frameworks like Spring MVC and Rails.

Dreisam works by serving FastCGI requests. To run Dreisam applications, FastCGI must be enabled in the webserver.

The FastCGI request are processed by the front controller dreisam.fcgi which must be placed in the appropriate directory (usually fcgi-bin).

At startup, dreisam.fcgi reads the configuration file fcgi-bin/dreisam/config.td and connects to a database environment.

An example configuration file looks like this:

dbenv := 'dreisam/data/dbenv';
current_db := 'SDB';

This means that the database environment directory is fcgi-bin/dreisam/data/dbenv and that the default database is SDB.

The database environment and the database need to be created. This can be done use the command line interpreter Duro D/T. See the Duro D/T tutorial for information on how to use the interpreter.

The database environment directory and all its files must be readable and writable by the webserver.

The simplest way to achieve this is to make the user under which the webserver runs the owner of the directory and its files. You then probably have to issue a 'sudo' to access the database from your user.

The script td/setup.td creates the necessary table and operators for processing requests. td/template.td contains the operators for template processing. These scripts must be run to make the Dreisam framework available.

A simple hello application

Let's create a small application which receives a name with the request and sends a hello message back.

First, we need an action. For an action there must be an entry in the http_actions table and an update operator.

So let's create both:

insert http_actions tup { path '/hello', opname 'hello', method 'GET' };

operator hello (model tup { name string }, view string) updates { model, view };
    ; /* Do nothing */
end operator;

This maps the path /hello to the action operator hello.

The action operator receives the request data in the model argument and a view name in the view argument.

The view name passed to the operator is the path without the leading slash, so it is simply 'hello'.

In this simple example, both the model and the view don't have to be modified, so the operator body doesn't do anything. The semicolon is there because at least one statement is required in the operator body.

When the action has been executed, the front controller maps the view name to a template and processes the template using the model. For a view named 'hello', the template is hello.thtml. Read more about the template language.

As templates are located in fcgi-bin/dreisam/views, let's create the following hello.thtml right there:


<p>Hello {$ m.name $}!


If we now issue a GET request by entering the following line into the browser's location field:


we get:

Hello John!


By setting the view to the empty string, an action can prevent the template rendering.

For example, an action which redirects to http://some_other_site.com/ using HTTP response code 303 can be created as follows:

insert http_actions tup { path '/redirect', opname 'redirect', method 'GET' };

operator redirect (model tup { }, view string, resp http.http_response) updates { model, view, resp };
    http.set_status(resp, 303);
    http.set_response_header(resp, 'Location', 'http://some_other_site.com/');
    view := '';
end operator;

The operators http.set_status and http.set_response_header require an argument of type http.http_response. This can be made available by adding an argument of this type to the action operator.

Sending JSON data

An action operator can send a JSON response using the operator http.send_json_response:

insert http_actions tup { path '/jsonexample', opname 'jsonexample', method 'GET' };

operator jsonexample (model tup { name string, no int, price float }, view string,
        resp http.http_response)
        updates { model, view, resp };
    model := tup { name 'Cap', no 22, price 10.97 };

    view := '';
    http.send_json_response(resp, model);
end operator;

The request


will produce the following output:

"no": 22,
"name": "Cap",
"price": 10.97