Introduction
Reactive Server Pages (RSP) bring some concepts of reactive languages to the realm of server-side web development.
Traditional server-side web application are implemented as a collection of related pages that access the same shared state (i.e. session variables). Once the web server receives a page request from the client, it executes the dynamic page reading and writing to session variables, and yields a fresh page to the client. The request is handled all at once, and no state (besides the client's session) remains in the server. Hence, there is no notion of sequential execution in a web application, whose life cycle is purely associated with the active client session.
RSP rearrange the way web applications are developed. A web application conceptually becomes a single file that executes from its first to its last line. The programmer can use structured programming with loops and recursive calls. RSP are based on LuaGravity, which extends the Lua language with reactive data and control primitives.
In the following example (which is available online), each time the
client accesses the path /next in the application (which triggers
the event next
), a new page with the counter incremented is generated to the
client:
_step = 1
_html = [[I am in step ]].._step
for i=1, 5 do
_step = i
await 'next'
end
_html = [[Finished!]]
In LuaGravity, any variable starting with underscores (i.e. _html
) is
reactive in the sense that it is reevaluated whenever one of its dependencies
changes.
In the example, whenever _step
changes, the _html
variable is automatically
reevaluated to respect the new value of _step
.
In RSP, the current value of the _html
variable is the actual page returned
to the client whenever the application becomes idle waiting for events.
After iterating from 1 to 5, generating five pages, and also the Goodbye! page, the application terminates. If the client accesses the application again, it restarts, generating the page I am in step 1.
This example illustrates both control and data reactivity in RSP: reactive variables account for data reactivity, while the await call, for control reactivity.
Architecture
An RSP application is accessed from a single URL in the server, as in
http://www.mydomain.com/rsp/myapp/
Accesses to the rsp/
directory are intercepted by the RSP runtime, which
executes the file myapp.lua
in the configured directory.
The application runs to completion or until it waits for events, and returns to
the client the current value of the reactive variable _html
.
The client interacts with the application in two forms: through events, or by changing reactive variables.
In the following URLs, the first triggers the event next
in myapp
, while
the second changes the value of _var
to zero:
http://www.mydomain.com/rsp/myapp/next
http://www.mydomain.com/rsp/myapp/?_var=0
The users do not need to type these URLs themselves, they can be generated by
links or forms in the application.
In the following example, the link points to the URL
http://www.mydomain.com/rsp/myapp/next
(which triggers the event next
in
myapp
); while typing rsp
in the text box, and pressing the submit button
points to the URL http://www.mydomain.com/rsp/myapp/submit?_name=rsp
(which
sets _name=rsp
before triggering the event submit
).
<a href="next">Click to go to next step</a>
<form>
<input type="text" name="_name"/>
<input type="submit" name="submit"/>
</form>
In order to support changing variables from the client side, an RSP application
must define a table pub
with the available variables:
local meta = require 'luagravity.meta'
pub = meta.new {
_name = ''
}
Trying to set an undefined variable raises an error.
Follows a summary of the architecture of RSP:
- Application
- Single file
- Execution = from first to last line
- State = globals + locals + PC
- Client interaction
- Events
- Reactive variables
- Interface
- The reactive variable
_html
- The reactive variable
An Example: A Shopping Cart
Click here for a more complex example of a simple shopping cart in RSP.
Download & Install
The current version of RSP is 0.1.1 and can be downloaded here.
I also keep a github repository here.
RSP depends on LuaGravity, wsapi, luacrypto, and lfs. To install wsapi-xavante, luacrypto and lfs, you can use luarocks:
# luarocks install lfs
# luarocks install luacrypto
# luarocks install wsapi-xavante
To install RSP, just unpack it to the desired destination:
# tar xvzf luarsp-0.1.1.tgz
Assuming that you will use wsapi-xavante, you can edit the file config.lua
to your preferences, and then run the server:
# cd luarsp-0.1.1/
# vi config.lua
# cd examples
# wsapi -c ../config.lua
Then, open your browser and point to one of the applications in the examples/
directory, for example:
http://localhost:8080/rsp/cart/
Acknowledgments
Please contact me if you are using RSP.
License
Reactive Server Pages is free software: it can be used for any purpose, including commercial purposes, at absolutely no cost. No paperwork, no royalties, no GNU-like "copyleft" restrictions, either. Reactive Server Pages is certified Open Source software. Its licenses are compatible with GPL.
The MIT License
Copyright (c) 2010 Francisco Sant'Anna
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.