Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/coderofsalvation/soakbean
Write beautiful ~2.3MB redbean (docker) apps using (redbean) plug-and-play middleware. #tiniest_fastest_server_in_the_universe
https://github.com/coderofsalvation/soakbean
crossplatform express fast lua microstack webserver
Last synced: about 1 month ago
JSON representation
Write beautiful ~2.3MB redbean (docker) apps using (redbean) plug-and-play middleware. #tiniest_fastest_server_in_the_universe
- Host: GitHub
- URL: https://github.com/coderofsalvation/soakbean
- Owner: coderofsalvation
- Created: 2021-11-13T11:11:11.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2024-01-05T10:30:39.000Z (11 months ago)
- Last Synced: 2024-08-03T17:08:02.804Z (4 months ago)
- Topics: crossplatform, express, fast, lua, microstack, webserver
- Language: Lua
- Homepage:
- Size: 3.49 MB
- Stars: 13
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-cosmopolitan - soakbean - like middleware. (Redbean / Projects)
README
## Reactive plugnplay middleware for redbean
Write beautiful ~2.3MB [redbean (docker) apps](https://redbean.dev) like this [.init.lua](src/.init.lua):
## Beautiful micro stack
* re-use middleware functions across redbean projects
* reactive programming (write less code)
* easy express-style routing
* easily adapt to redbean API changes## Syntactic sugar
```lua
app = require("soakbean") {
bin = "./soakbean.com",
opts = { my_cli_arg=0 },
cmd={
-- runtask = {file="sometask.lua", info="description of cli cmd"}
},
title = 'SOAKBEAN - a buddy of redbean',
}app.url['^/data'] = '/data.lua' -- setup custom file endpoint
--
app.get('^/', app.template('index.html') ) -- alias for app.tpl( LoadAsset('index.html'), app )
-- also see app.post app.put and so on
app --
.use( require("json").middleware() ) -- try plug'n'play json API middleware
.use( app.router( app.url ) ) -- try url router
.use( app.response() ) -- try serve app response (if any)
.use( function(req,next) Route() end) -- fallback default redbean fileserverfunction OnHttpRequest() app.run() end
```Just run it straight from the repository using [redbean.com](https://redbean.dev) itself:
```
$ git clone https://github.com/coderofsalvation/soakbean && cd src
$ redbean.com -D . --my-cli-arg=abc
```Then you can easily package the current directory into your own (renamed redbean) COM-file:
```
$ sed -i 's/NAME=soakbean/NAME=yourapp/g'
$ ./make all
$ ./yourapp.com --my-cli-arg=abc
```> Profit!
## Getting started
| Lazy | Recommended | Docker |
|-|-|-|
| download [soakbean.com](https://github.com/coderofsalvation/soakbean/raw/master/soakbean.com), add html (and/or lua) files using a zip-filemanager, and run `./soakbean.com` | download [redbean.com](https://redbean.dev) and run it in the `src` folder of this repo (see above cmdline) | clone this repo and run `./make docker` and surf to `http://localhost:8080` |> middleware: copy [middleware](middleware) functions to `src/.lua`-folder where needed
## Cute simple backend<->frontend traffic
Just look at how cute this [index.html](src/index.html) combines serverside templating with RESTful & DOM-reactive templating:
```
${title} <-- evaluated serverside -->
<-- evaluated clientside -->
<-- evaluated clientside using REST call to server -->
```## Middleware functions
You can easily manipulate the http-request flow, using existing middleware functions:
```lua
app.use(
require("blacklisturl")({
"^/secret/",
"^/me-fainting-next-to-justinbieber.mp4"
})
)
```> make sure you copy [middleware/blacklisturl.lua](middleware/blacklisturl.lua) to [src/.lua](src/.lua)
or just write ad-hoc middleware:
```lua
app.use( function(req,res,next)
res.status(200)
res.header('content-type','text/html')
res.body('hello world')
next() -- comment this to prevent further middleware altering body, status headers e.g.
end)
``````lua
app.use( function(req,res,next)
if !req.loggedin && req.url:match("^/mydata") then
res.status(403)
else next()
end)
```> WANTED: please contribute your [middleware](middleware) functions by pushing repositories with nameconvention `soakbean-middleware-`. Everybody loves (re)using battle-tested middleware.
## req & res object
| key | type | alias for redbean |
|-|-|-|
| `req.method` | string | `GetMethod()` |
| `req.url` | string | `GetPath()` |
| `req.param` | table | `GetParams()` |
| `req.host` | string | `GetHost()` |
| `req.header` | table | `GetHeaders()` |
| `req.protocol` | string | `GetScheme()` |
| `req.body` | table or string | |
| `res.body(value)` | string | `Write(value) including auto-encoding (json e.g.)` |
| `res.status(code)` | int | `SetStatus(code)` |
| `res.header(type,value)` | string,string | `SetHeader(type,value)` |## Simple template evaluation
index.html
```
${title}
```lua
```
app.title = "hello world"
app.get('^/', app.template('index.html') )
```> NOTE: this is basically serving the output of `app.tpl( LoadAsset('index.html'), app )`
## Reactive programming
#### react to variable changes:
```lua
app.on("foo", function(k,v)
print("appname changed: " .. v)
end)app.foo = "flop" -- output: appname changed: flop
app.foo = "bar" -- output: appname changed: bar
```#### react to function calls
```lua
app.on('foobar', function(a)
print("!")
end)app.foobar = function(a)
print('foobar')
endapp.foobar() -- output: foobar!
```#### react to router patterns
```lua
app.url['^/foo'] = '/somefile.lua'app.on('^/foo', function(a,b)
-- do something
end)
```#### react to luafile endpoint execution
```lua
app.url['^/foo'] = '/somefile.lua'app.on('somefile.lua', function(a,b)
-- do something
end)
```#### react to response code/header/body changes
```lua
app.on('res.status', print )
app.on('res.body' , print )
app.on('res.header', function(k,v)
print(k .. " => " .. v)
end)
```> NOTE: above is handy for debugging a flow. Use `app.use(..)` for more control.
## Roadmap / Scope
* scope is backend, not frontend
* http auth (*)
* middleware: sqlite user sessions (*)
* middleware: sqlite tiny job queue (*)
* middleware: sqlite tiny rule engine (*)
* middleware: sqlite CRUD middleware (endpoints + sqlite schema derived from jsonschema) (*)\* = please contribute! =]