How to write a Fantom Web Server in just 7 lines of code!
This web application will serve up static files from your file system. It is the smallest, yet usable, web application I could think of!
Once running, it maps all incoming HTTP requests to files in the C:\Projects\ directory. So if you keep your HTML and CSS files there, they would all be available from a web browser.
Create the web server in these small steps!
1). It uses BedSheet v1.5 so first make sure you have it installed in your Fantom environment.
fanr install -r http://eggbox.fantomfactory.org/fanr "afBedSheet 1.5"
2). Create a text file called WebServer.fan in C:\Projects\:
using afIoc
using afBedSheet
class WebServer {
Int main() {
BedSheetBuilder(AppModule#.qname).startWisp(8080)
}
}
const class AppModule {
@Contribute { serviceType=FileHandler# }
static Void contributeFileHandler(Configuration conf) {
conf[`/`] = `file:C:/Projects/`
}
}
Note: Okay, so the pedantic amongst you would have counted more than 7 lines of code there. But if you delete some whitespace and fully qualify the class names you can actually write it in 5 lines of code!
So I think advertising 7 lines is a happy compromise! :p
3). Run WebServer.fan as a Fantom script from the command line:
C:\Projects>fan WebServer.fan
[info] [afBedSheet] Found mod 'WebServer_0::AppModule'
[info] [web] http started on port 8080
[info] [afBedSheet] Starting Bed App 'WebServer_0' on port 8080
[info] [afIoc] Adding module WebServer_0::AppModule
[info] [afIoc] Adding module afBedSheet::BedSheetModule
[info] [afIoc] Adding module afIocConfig::IocConfigModule
[info] [afIoc] Adding module afBedSheet::BedSheetEnvModule
[info] [afIoc] Adding module afConcurrent::ConcurrentModule
[info] [afIoc]
27.03% of services were built on startup (10/37)
___ __ _____ _
/ _ | / /_____ _____ / ___/__ ___/ /_________ __ __
/ _ | / // / -_|/ _ /===/ __// _ \/ _/ __/ _ / __|/ // /
/_/ |_|/_//_/\__|/_//_/ /_/ \_,_/__/\__/____/_/ \_, /
Alien-Factory BedSheet v1.5.2, IoC v3.0.2 /___/
[info] [afIoc] IoC Registry built in 220ms and started up in 498ms
Bed App 'WebServer_0' v0 listening on http://localhost:8080/
4). Point your browser to http://localhost:8080/WebServer.fan and watch the application serve itself!
How Does It Work?
The main() method starts BedSheet, passing in the fully qualified name of the module class ( AppModule ) and the port to listen on ( 8080 ).
Classes in scripts do have fully qualified names, even though they're not officially part of a pod. That is because, behind the scenes, Fantom creates a transient pod to temporarily house the scripts in. You can see this in the log message:
[info] [afIoc] Adding module WebServer_0::AppModule
The AppModule itself does nothing more than configure the FileHandler service. The FileHandler service then maps these requests to the C:\Projects\ directory.
To serve files under a different URL, say /poo, change the configuration line to:
conf[`/poo`] = `file:C:/Projects/`
Now the script is served under http://localhost:8080/poo/WebServer.fan.
We could also change the configuration to always serve files from the same directory as the script:
conf[`/poo`] = `./`
Of course, you could put any directory in there, just make sure it ends with a trailing slash.
Note the file: scheme was only required because originally we had a Windows path starting with C:/.
Epilogue
We've just seen how to use a Fantom script to start a mini BedSheet web application that serves files. We then changed the FileHandler configuration to serve files under different URLs and from different directories.
Brilliant!
Have fun!
Edits
- 29 July 2016 - Updated example to BedSheet 1.5.
- 17 June 2014 - Updated example from File Server to Web Server, added BedSheet output.
- 26 November 2013 - Original article.