Skip to content

Server Module

REST Microservice - Lightweight server exposing core flow APIs as REST endpoints.


The Server module (server/) provides a minimal REST API that wraps the core flow engine. It’s designed for use by external applications like Bun/JavaScript or PHP implementations.


Use CaseDescription
Bun IntegrationJavaScript/TypeScript clients using Bun
PHP IntegrationPHP applications calling flow APIs
Standalone ExecutionRun flows without the full backend
MicroserviceLightweight flow execution service

Terminal window
# Default (port 8080, current directory)
./server
# Custom port and path
./server -port 3000 -path ./storage/dbs
# Help
./server help
FlagDefaultDescription
-port8080HTTP port to listen on
-path./Path for SQLite databases

MethodEndpointDescription
POST/loadLoad flow into workspace
POST/runRun initial node
POST/continueContinue to next node
POST/pushPush node results
POST/interruptInterrupt execution
POST/mapperExecute mapper transformation
MethodEndpointDescription
GET/data-store-listList data stores
POST/data-store-createCreate data store
PUT/data-store-update/{id}Update data store
GET/data-structure-listList data structures
POST/data-structure-createCreate data structure
PUT/data-structure-update/{id}Update data structure

Load a flow into the workspace:

POST /load
Content-Type: application/json
{
"flow_id": "flow-123",
"flow": {
"nodes": [...],
"edges": [...]
}
}

Response:

{
"status": "success",
"message": "Flow loaded"
}

Run the initial node:

POST /run
Content-Type: application/json
{
"flow_id": "flow-123",
"node_id": "n_1",
"target_id": "output"
}

Response:

{
"params": {...},
"queue": {...},
"node": {...}
}

Continue to the next node:

POST /continue
Content-Type: application/json
{
"flow_id": "flow-123"
}

Response:

{
"params": {...},
"queue": {...},
"node": {...}
}

Returns null when flow is complete.

Push node execution results:

POST /push
Content-Type: application/json
{
"flow_id": "flow-123",
"ots": [
{"target_handle": "output", "data": {...}}
],
"message": "Success",
"status": "success"
}

Response:

{
"status": "success",
"queues": [...],
"edges": [...],
"outputs": [...]
}

Execute a mapper transformation:

POST /mapper
Content-Type: application/json
{
"flow_id": "flow-123",
"node_id": "n_5"
}

Complete execution flow using the REST API:

// JavaScript/Bun example
async function executeFlow(flowId, flow, startNode) {
const base = 'http://localhost:8080';
// 1. Load flow
await fetch(`${base}/load`, {
method: 'POST',
body: JSON.stringify({ flow_id: flowId, flow })
});
// 2. Run initial node
let response = await fetch(`${base}/run`, {
method: 'POST',
body: JSON.stringify({
flow_id: flowId,
node_id: startNode,
target_id: 'output'
})
}).then(r => r.json());
// 3. Execution loop
while (response && response.queue) {
// Process node (your logic)
const outputs = processNode(response.node, response.params);
// Push results
await fetch(`${base}/push`, {
method: 'POST',
body: JSON.stringify({
flow_id: flowId,
ots: outputs,
message: 'ok',
status: 'success'
})
});
// Continue
response = await fetch(`${base}/continue`, {
method: 'POST',
body: JSON.stringify({ flow_id: flowId })
}).then(r => r.json());
}
console.log('Flow completed');
}

graph LR
Client[External Client] -->|HTTP| Server
Server -->|calls| Core[Core Module]
Core -->|persists| SQLite[(SQLite)]

package main
func main() {
// Parse CLI flags
port := flag.Int("port", 8080, "Port to listen")
path := flag.String("path", "./", "Path to store the data")
// Set SQLite path
db.DB_PATH = *path
// Setup routes
mux := http.NewServeMux()
mux.HandleFunc("/load", loadHandler)
mux.HandleFunc("/run", runHandler)
mux.HandleFunc("/continue", continueHandler)
mux.HandleFunc("/push", pushHandler)
mux.HandleFunc("/mapper", mapperHandler)
// Storage routes
storageController := controllers.NewStorageController()
mux.HandleFunc("/data-store-list", storageController.ListStores)
// ...
// Start server with CORS
http.ListenAndServe(fmt.Sprintf(":%d", *port), corsMiddleware(mux))
}

The server includes permissive CORS middleware:

func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}

LibraryPurpose
github.com/mattn/go-sqlite3SQLite driver
gitlab.com/altacrest/flow_binaries/coreCore flow engine

Terminal window
cd server
go build -o flow-server .