A webapp is an application container for RSP scripts. It is a way to group together some RSP scripts and static files, and provide them with several useful services. A webapp is defined in the configuration file, in Host sections. It basically associates a virtual path with a root folder in the filesystem, everything inside that folder becomes part of the webapp.
A minimal webapp definition would look like this:
webapp [ virtual-root "/app" root-dir %www/app/ ]
This webapp will be further referenced in Cheyenne by its virtual-root? value, so this value have to be unique inside a given virtual-host definition. You can have as many webapps as you want in the same virtual-host (even pointing at the same root folder to make multiple instances of the same webapp using different settings, like using a different database instance).
A webapp uses a specific filesystem folder structure:
app/ ;-- webapp root folder private/ ;-- private folder, not visible for clients public/ ;-- folder always accessible for clients app-init.r ;-- mandatory file for events definition ... ;-- put there all the protected files (RSP, static files)
The only mandatory part is the %app-init.r file (see Events section below). This file is private to the webapp and can't be served to clients (they will get a 404 HTTP code if they try).
This is an optional folder, but will be used by most webapps. It is the most secured part of the webapp files hierarchy as it can't be accessed by client requests. Its purpose is to contain all the backend code of your web application: utility functions, libraries, frameworks, SQL files, localizations data, ...
This is an optional folder used to store public files that have to be accessible by clients in all cases. Even if the webapp authentication? protection is active, the resources stored in this folder can still be served to the client. The main use-case is storing static resources required by a login page.
Everything that is not in public/ or private/ folders can be freely accessed by the clients unless the webapp authentication? is activated (see Session management below). In such case, every attempt to access a resource will result in a redirection to the authentication page, if the user hasn't logged-in yet (controlled by the state of session/content/login special variable).
One of the main benefit from using a webapp container is the automatic session management. Every new client requesting any RSP script inside your webapp, will open a new session. The session is opened for 20 minutes by default (timeout delay) and can be extended using the timeout? configuration directive in the webapp definition block.
A special login word is added to session/content, with a value of false. If the auth? configuration directive is present in the webapp definition, this value indicates the state of the user authentication. It is used internally by the webapp to secure access to all its files, until the user logs in and an RSP script sets the login value to true, giving access to all the files. So a webapp protected by authentication would be defined like this:
webapp [ virtual-root "/app" root-dir %www/app/ auth "/app/login.rsp" ]
A webapp exposes several events that can be caught by implementing custom handlers in the special %app-init.r file (located in the root folder of the webapp). This file is mandatory for all webapps, even if you don't use it. Here's a template that you can copy/paste (you can safely remove the handler functions you don't need):
REBOL [ File: %app-init.r Purpose: "Events definition for webapp /app" ] on-application-start: does [ ;--- add here your library / modules loading ] on-application-end: does [ ;--- add here your library / modules proper closing ] on-database-init: does [ ;--- add here instance specific init code ] on-session-start: does [ ;--- add here your per session init code ] on-session-end: does [ ;--- add here your per session closing/cleanup code ] on-page-start: does [ ;--- add here processing code run before a RSP page is evaluated ] on-page-end: does [ ;--- add here processing code run after a RSP page is evaluated ]
: the %app-init.r file content is cached in memory in worker processes. If you modify its content, your changes will not be taken into account, you need to reset workers? processes to apply your changes or run Cheyenne with a non-persistent? worker ("-w 0" command-line option).
When using several instances of the same webapp, you often need a way to pass them some parameters that are instance-specific. You can achieve that easily by adding a locals? block to your webapp definitions:
webapp [ virtual-root "/app1" root-dir %www/app/ locals [ title "App1" data-dir %private/app1/ ] ] webapp [ virtual-root "/app2" root-dir %www/app/ locals [ title "App2" data-dir %private/app2/ ] ]
You can access these locals values in your RSP code using request/config/locals.
: there is a performance impact when using locals blocks, so keep them as small as possible.