
WebApp
Overview
WARNING: the webapp framework is still an early prototype, so will be going through many changes during development
The webapp pod defines a framework for building web applications by assembling prebuilt WebSteps
:
- FindResourceStep: maps the request URI to a Fan obj which represents a resource in the VM's local namespace
- FindViewStep: find a suitable Weblet which can service the request and provide a representation of the resource
- FindChromeStep: lets you plug in a common look and feel across all your views
- ServiceViewStep: does it
- LogStep: logs using W3C extended log format
FindResourceStep
FindResourceStep
is responsible for mapping the web request URI to a Fan object which represents the the resource to service. This object can be anything, but is typically a File or an object in the domain model (such as a row in the database). In most cases, the web request URI is mapped directly to the local namespace via Sys.ns
. But FindResourceStep
also provides the following features:
- Defines the home page resource
- Searches for file extensions
- Searches for the index file to use for a directory
- Redirects to use trailing slash on directories
- Returns 404 if resource isn't found
Let's take an example:
// pipeline step config FindResourceStep { extSearch = ["fan", "html", "txt"].toImmutable dirIndex = ["index.fan", "index.html"].toImmutable } // setup Sys.ns.create(`/homePage`, scriptDir + `home.html`) Sys.mount(`/dir`, Namespace.makeDir(scriptDir + `dir/`)) // application directory boot.fan home.html dir/ index.fan subdir/ index.html script.fan test.txt
Since we didn't configure the homePage
field, it defaults to "/homePage", which is the resource object we'll use for servicing "/". In our setup we map "/homePage" to the "home.html" file in the same directory as our boot script.
Since we configured extSearch
, we can use the following URIs with or without extensions:
/dir/index => /dir/index.fan /dir/index.fan => /dir/index.fan /dir/subdir/script => /dir/subdir/script.fan /dir/subdir/script.fan => /dir/subdir/script.fan /dir/subdir/test => /dir/subdir/test.txt /dir/subdir/test.txt => /dir/subdir/test.txt
When processing directories we use the dirIndex
field to search the directory for its index file. We also check if the web request is accessing a directory URI without a trailing slash, in which case we do a redirect to keep relative hrefs working:
/dir => redirects to /dir/ /dir/ => /dir/index.fan /dir/subdir => redirects to /dir/subdir/ /dir/subdir/ => /subdir/index.html
If you want your own resource objects to take advantage of the trailing slash redirect, you need only declare a isDir()
method which return true.
FindViewStep
FindViewStep
is responsible for finding a Weblet
to service the request by returning an appropriate representation of the resource found by FindResourceStep
.
If the resource is itself a Weblet
, then the view is the resource itself. Otherwise the type database is queried for a type which declares itself a "webView" on the resource type. For example:
@webView=Invoice.type class InvoiceView : Weblet {}
File resources are automatically handled by the web::FileWeblet
which handles all the dirty details for cache control, modification time, ETags, etc.
FindChromeStep
FindChromeStep
is used to create a pluggable look and feel or theme for a web application. The chrome is just a normal webapp::Widget
which wraps the view Widget
. If the view isn't a Widget
, then the chrome has no effect.
ServiceViewStep
ServiceViewStep
class is a simple class which calls Weblet.service
on the view weblet.
LogStep
LogStep
class is used to generate a server log file for all HTTP requests in the W3C Extended Log File Format. The file
Uri must be configured - records are always appended to this file. Logging is done on the onAfterService
callback.
The fields
property configures the format of the log records. It is a string of field names separated by a space. The following field names are supported:
- date: UTC date as DD-MM-YYYY
- time: UTC time as hh:mm:ss
- cs-method: the request method such as GET
- cs-uri: the encoded request uri (path and query)
- cs-uri-stem: the encoded path of the request uri
- cs-uri-query: the encoded query of the request uri
- sc-status: the return status code
- time-taken: the time taken to process request in milliseconds
- cs(HeaderName): request header value such
If any unknown fields are specified or not available then "-" is logged. The default format is:
date time cs-method cs-uri-stem cs-uri-query sc-status time-taken cs(User-Agent) cs(Referrer)
Example log record with this format:
09-04-2008 01:19:07 - GET /dir/index - 200 85 "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13" -