Hi Otto,,, our conversation was more about microservices, but HIX is absolutely very powerful,,,, it can create microservices as you say,,,, once the sql libraries are added to it,,,, and the multi-thread from harbour,,, you can have something as strong as apache,,,, here is a sample,,,, with persistent and transient microservices....
I love that HIX is and will serve the community,,, I even donated to the HIX event, even when i knew I wasn't going to be able to assist... I also buy Fivewin from time to time, not because i use it, but because i love it, since i saw it in compuserve magazine.... and I would love to see HIX and Fivewin growing along Harbour and xHarbour,,,, we all are working to make sure xBase coding doesn't die...

//backend_persistent.prg
// HIX Backend - Persistent Service
// Uses a simple JSON file to simulate persistent state across requests,
// bypassing thread/process isolation issues.
#pragma -w0
#pragma -es0
FUNCTION Main()
LOCAL hState := {=>}
LOCAL cStateFile := "server_state.json"
LOCAL cJson_In, cJson_Out
LOCAL hResponse := {=>}
// 1. LOAD STATE (Persistence Layer)
IF File( cStateFile )
cJson_In := MemoRead( cStateFile )
hState := hb_jsonDecode( cJson_In )
ELSE
hState[ "hits" ] := 0
hState[ "start_time" ] := Time()
ENDIF
// 2. MODIFY STATE
hState[ "hits" ] := hState[ "hits" ] + 1
// 3. SAVE STATE
hb_MemoWrit( cStateFile, hb_jsonEncode( hState ) )
// 4. PREPARE RESPONSE
hResponse[ "type" ] := "PERSISTENT"
hResponse[ "status" ] := "ok"
hResponse[ "hits" ] := hState[ "hits" ]
hResponse[ "server_start" ] := hState[ "start_time" ]
hResponse[ "message" ] := "State Updated"
?? hb_jsonEncode( hResponse )
RETURN ""
//backend_transient.prg
// HIX Backend - Transient Service
// Stateless microservice. Does not read or write the shared state file.
#pragma -w0
#pragma -es0
FUNCTION Main()
LOCAL hResponse := {=>}
// 1. DO WORK (Stateless)
hResponse[ "type" ] := "TRANSIENT"
hResponse[ "status" ] := "ok"
hResponse[ "server_now" ] := Time()
hResponse[ "message" ] := "Just a quick calculation"
// We do NOT return 'hits' because we don't know them and don't care.
?? hb_jsonEncode( hResponse )
RETURN ""
//client.prg
// HIX Client Logic (Server-Side)
// Uses a FUNCTIONAL approach instead of CLASS to avoid HRB syntax issues.
// Accessed via http://localhost:8080/client.prg
// Include HIX header just in case, though we rely on pure functions
#include "c:\xampp2025\htdocs\webx\hix\hix.ch"
FUNCTION Main()
LOCAL hPage := THtml_New()
THtml_SetTitle( hPage, "HIX Microservice Client" )
THtml_CSS( hPage, "body { font-family: 'Segoe UI', sans-serif; background: #222; color: #eee; text-align: center; padding: 50px; }" )
THtml_CSS( hPage, "button { padding: 15px 30px; font-size: 18px; margin: 20px; cursor: pointer; border: none; border-radius: 4px; transition: transform 0.1s; }" )
THtml_CSS( hPage, ".btn-p { background: #d81b60; color: white; }" ) // Pink for Persistent
THtml_CSS( hPage, ".btn-t { background: #00bcd4; color: white; }" ) // Cyan for Transient
THtml_CSS( hPage, "button:active { transform: scale(0.95); }" )
THtml_CSS( hPage, "#result { margin-top: 20px; padding: 20px; border: 1px solid #444; background: #333; min-height: 100px; }" )
THtml_AddContent( hPage, "<h1>HIX Microservice Demo</h1>" )
THtml_AddContent( hPage, "<p>Select a Thread Model:</p>" )
// Two distinct buttons calling different endpoints
THtml_AddButton( hPage, "Persistent Call", "callService('backend_persistent.prg')", "btn-p" )
THtml_AddButton( hPage, "Transient Call", "callService('backend_transient.prg')", "btn-t" )
THtml_AddContent( hPage, "<div id='result'>Ready...</div>" )
// JS Logic - Corrected JSON escaping
THtml_AddScript( hPage, ;
"async function callService( endpoint ) { " + ;
" const resDiv = document.getElementById('result'); " + ;
" resDiv.innerHTML = 'Executing ' + endpoint + '...'; " + ;
" try { " + ;
" const resp = await fetch(endpoint + '?_=' + Date.now()); " + ;
" let text = await resp.text(); " + ;
" text = text.replace('NIL', '').trim(); " + ;
" const data = JSON.parse(text); " + ;
" let html = ''; " + ;
" html += '<h3 style=\x22color:' + (data.type==='PERSISTENT'?'#f06292':'#4dd0e1') + '\x22>' + data.type + ' RESPONSE</h3>'; " + ;
" html += '<b>Message:</b> ' + data.message + '<br>'; " + ;
" if(data.hits) html += '<b>Total Hits (Persistent):</b> ' + data.hits + '<br>'; " + ;
" if(data.server_start) html += '<b>Server Started:</b> ' + data.server_start + '<br>'; " + ;
" if(data.server_now) html += '<b>Current Time:</b> ' + data.server_now + '<br>'; " + ;
" resDiv.innerHTML = html; " + ;
" } catch(e) { " + ;
" resDiv.innerHTML = 'Error: ' + e + '<br><small>Raw: ' + (typeof text !== 'undefined' ? text : 'Network Error') + '</small>'; " + ;
" } " + ;
"}" )
?? THtml_GetHtml( hPage )
RETURN ""
// --------------------------------------------------------------------------
// PSEUDO-CLASS THtml (Using Hash)
// --------------------------------------------------------------------------
FUNCTION THtml_New()
LOCAL hObj := {=>}
hObj[ "title" ] := "HIX Page"
hObj[ "head" ] := ""
hObj[ "body" ] := ""
hObj[ "script" ] := ""
RETURN hObj
FUNCTION THtml_SetTitle( hObj, cText )
hObj[ "title" ] := cText
RETURN NIL
FUNCTION THtml_CSS( hObj, cRules )
hObj[ "head" ] += "<style>" + cRules + "</style>" + Chr(13)+Chr(10)
RETURN NIL
FUNCTION THtml_AddContent( hObj, cHtml )
hObj[ "body" ] += cHtml + Chr(13)+Chr(10)
RETURN NIL
FUNCTION THtml_AddButton( hObj, cLabel, cAction, cClass )
LOCAL cCls := ""
IF ValType(cClass) == "C" ; cCls := " class='" + cClass + "'" ; ENDIF
hObj[ "body" ] += '<button' + cCls + ' onclick="' + cAction + '">' + cLabel + '</button>' + Chr(13)+Chr(10)
RETURN NIL
FUNCTION THtml_AddScript( hObj, cJs )
hObj[ "script" ] += cJs + Chr(13)+Chr(10)
RETURN NIL
FUNCTION THtml_GetHtml( hObj )
LOCAL cHtml := ""
cHtml += "<!DOCTYPE html>" + Chr(13)+Chr(10)
cHtml += "<html>" + Chr(13)+Chr(10)
cHtml += "<head>" + Chr(13)+Chr(10)
cHtml += " <meta charset='UTF-8'>" + Chr(13)+Chr(10)
cHtml += hObj["head"]
cHtml += " <title>" + hObj["title"] + "</title>" + Chr(13)+Chr(10)
cHtml += "</head>" + Chr(13)+Chr(10)
cHtml += "<body>" + Chr(13)+Chr(10)
cHtml += hObj["body"]
cHtml += " <script>" + Chr(13)+Chr(10)
cHtml += hObj["script"]
cHtml += " </script>" + Chr(13)+Chr(10)
cHtml += "</body>" + Chr(13)+Chr(10)
cHtml += "</html>"
RETURN cHtml
You can have multi-threads, instead of separate .exe files, make your code for a persistent database, so you dont have to wait 1 minute for it to load,,,, Harbour is very powerful...
I'm not challenging your approach either,,,, but multiple .exe, is a problem,,,, which one is compiled?, which one is not?,,, instead of a single point of source.... Apache is a single .exe serving billions of microservices,,,, Harbour is as good, or we will soon find out...