How to create a BedSheet Extension for SkySpark 3.0
BedSheet is a great Fantom framework for web applications. It provides not only an IoC container but also a rich Middleware mechanism for routing and manipulating HTTP content. But given I wrote BedSheet, I guess I'm also quite biased!
Anyway, BedSheet is built on top of Fantom's Wisp, one of the cornerstones of SkySpark. So just for fun I thought I'd build a SkySpark web extension that integrates with a BedSheet application - and it turned out to be quite easy.
Following is a SkySpark web Ext that delegates all web requests to BedSheet.
using skyarcd::Ext using skyarcd::ExtMeta using concurrent::AtomicRef using afIoc using afBedSheet::MiddlewarePipeline using web::Weblet @ExtMeta { name = "bedsheet" } const class BedSheetExt : Ext, Weblet { private const AtomicRef registryRef := AtomicRef(null) private Registry registry { get { registryRef.val } set { registryRef.val = it } } private const AtomicRef pipelineRef := AtomicRef(null) private MiddlewarePipeline pipeline { get { pipelineRef.val } set { pipelineRef.val = it } } override Void onStart() { this.registry = RegistryBuilder().addModulesFromPod("afBedSheet").addModule(AppModule#).build this.pipeline = registry.activeScope.serviceById(MiddlewarePipeline#.qname) } override Void onService() { registry.activeScope.createChild("request") {// this is the actual call to BedSheet!pipeline.service } } override Void onStop() { registry.shutdown } }
The actual BedSheet application I used is just the Quick Start example from the BedSheet documentation.
using afIoc using afBedSheet const class AppModule { @Contribute { serviceType=Routes# } Void contributeRoutes(Configuration conf) { conf.add(Route(`/`, Text.fromHtml("<html><body>Welcome to BedSheet!</body></html>"))) conf.add(Route(`/hello/**`, HelloPage#hello)) } } class HelloPage { Text hello(Str name, Int iq := 666) { return Text.fromPlain("Hello! I'm $name and I have an IQ of $iq!") } }
And for completeness, here is my build.fan
using build class Build : BuildPod { new make() { podName = "afBedSheetExt" summary = "My Awesome BedSheetExt Project" version = Version("1.0") index = [ "skyarc.ext": "afBedSheetExt::BedSheetExt" ] depends = [// ---- Core Fantom ----"sys 1.0.69 - 1.0", "web 1.0.69 - 1.0", "concurrent 1.0.69 - 1.0",// ---- Sky Spark ----"skyarcd 3.0.6 - 3.0",// ---- BedSheet ----"afIoc 3.0.4 - 3.0", "afBedSheet 1.5.2 - 1.5", ] srcDirs = [`fan/`] resDirs = [`locale/`] } }
It was then a simple case of building the pod, adding it to SkySpark and enabling the ext
in an example project.
I then used the following URLS to test the BedSheet application:
C:\> curl http://localhost:8080/api/example/ext/bedsheet/ <html><body>Welcome to BedSheet!</body></html> C:\> curl http://localhost:8080/api/example/ext/bedsheet/hello/Traci/69 Hello! I'm Traci and I have an IQ of 69! C:\> curl http://localhost:8080/api/example/ext/bedsheet/hello/Luci Hello! I'm Luci and I have an IQ of 666!
And I could see the usual re-assuring Alien-Factory logo in the SkySpark console window.
Note that BedSheet has it's own pod dependencies which also need copying to SkySpark's /lib/fan/
dir:
But how you may maintain and distribute these with your SkySpark application is an entirely different problem!
Edits
- 29 April 2017 - Posted article on Alien-Factory.
- 18 October 2016 - Original article posted on SkyFoundry Forum.