Manuale di riferimento MALDA™

Il linguaggio di programmazione AI-First - Versione 1.0.11

25. HttpServer e generazione UI HTML

Questo capitolo copre il web server route-first di MALDA, gli handler di pagine HTML, gli helper per pagine generate dall'AI e le utility di cache HTML. Usalo quando vuoi servire pagine con HttpServer e route tradizionali richiesta/risposta.

Parti da qui: Leggi 23. Panoramica Web UI per confrontare i modelli UI. Questo capitolo si concentra su HttpServer, @PAGE, @AIPAGE e gli helper di generazione HTML. Per i componenti server e ui.*, vedi Componenti server Web UI. Per le route API-first, vedi Server REST API.

25.1 Mappa del capitolo

25.2 Classe HttpServer

La classe HttpServer offre un HTTP server built-in per asset statici, HTML generato sul server, pagine generate dall'AI, gestione dei form e handler di route. Funziona bene per applicazioni route-first in cui ogni richiesta restituisce un documento completo o una risposta mirata.

25.2.1 Costruttore

var server = new HttpServer(port);
// OR
var server = new HttpServer(port, webDirectory);  // Custom web directory
// OR
var server = new HttpServer(port, webDirectory, pathBase, host);

port deve essere un intero in 1-65535. Le porte privilegiate (1-1023, es. 80/443) sono ammesse; il bind può comunque richiedere permessi elevati o reservation URL del sistema operativo.

L'host di bind di default è localhost (solo loopback). Passa host come quarto argomento opzionale, chiama setHost(host) prima di start(), oppure imposta la variabile d'ambiente MALDA_HTTP_HOST. Usa 0.0.0.0 o * per ascoltare su tutte le interfacce (stesse regole di prefisso di RestServer). L'host di bind corrente è disponibile come proprietà host.

HTTPS è opzionale e cross-platform. Chiama enableHttps(certPath, password?) prima di start() con un file .pfx/.p12, oppure un PEM .pem/.crt (chiave privata accanto come .key). Alternative da ambiente: MALDA_HTTP_HTTPS=1, MALDA_HTTP_CERT e, opzionale, MALDA_HTTP_CERT_PASSWORD. Proprietà: https, certPath. Il TLS è terminato da Kestrel; la pipeline di richiesta esistente continua a girare su un HttpListener in loopback.

25.2.2 Metodi core

25.2.3 Esempio host minimo

var server = new HttpServer(8080);
server.start();

print("Server running at http://localhost:8080");

while (server.isRunning) {
    sleep(1000);
}

// HTTPS (optional):
// var tls = new HttpServer(8443);
// tls.setHost("0.0.0.0");
// tls.enableHttps("ask.pfx", "secret");
// tls.start();
// print("Server running at https://localhost:8443");

25.3 Oggetti request e response

Gli handler di pagine e route possono ricevere il contesto della richiesta e restituire HTML grezzo oppure un oggetto response strutturato.

Quando una route è in stile API, i fallimenti del framework restituiscono un payload JSON standardizzato con status, error, message e correlationId, con details opzionale per i fallimenti di validazione.

25.4 Pagine dinamiche con @PAGE

Usa @PAGE per pagine HTML guidate dalla richiesta. Un handler di pagina può restituire direttamente un documento HTML completo, e i path parameter vengono bound dall'URL.

@PAGE("/")
function handleHome() {
    return "<html><body><h1>Home</h1></body></html>";
}

@PAGE("/user/{id}")
function handleUser(id) {
    return "<html><body><h1>User: " + id + "</h1></body></html>";
}

Usa @PAGE quando la richiesta deve produrre una pagina completa. Se la pagina ha bisogno di fragment interattivi, aggiornamenti live o stato dei componenti gestito sul server, sposta la UI riutilizzabile in un flusso a componenti e tieni la route come punto di ingresso.

25.5 Pagine generate dall'AI con @AIPAGE

Usa @AIPAGE quando vuoi che MALDA generi l'HTML iniziale a partire da una descrizione in stile prompt.

@AIPAGE("/", "Contact form with name, email, and message fields")
function homePage() {
    // AI generates the HTML automatically on first access
    return "";
}

25.5.1 Esempio completo di form AI

var server = new HttpServer(8080);

@AIPAGE("/", "Contact form with name, email, and message fields")
function homePage() {
    return "";
}

@POST("/submit")
function handleSubmit(body) {
    print("Form submitted!");
    print("Name: " + body.name);
    print("Email: " + body.email);
    print("Message: " + body.message);

    return {
        "status": 200,
        "body": "<html><body><h1>Thank You!</h1><p>Your message has been received.</p><p><a href='/'>Back to form</a></p></body></html>"
    };
}

server.start();

25.6 Route GET/POST nei flussi di hosting delle pagine

HttpServer può ospitare route @GET e @POST insieme alle pagine. È utile per handler AJAX, piccoli endpoint JSON o Server-Sent Events usati da una pagina. Per la progettazione API completa, la validazione avanzata e l'organizzazione degli endpoint, usa Server REST API come riferimento principale.

25.6.1 Handler GET

@GET("/api/users")
function getUsers() {
    return {"status": 200, "users": ["Alice", "Bob", "Charlie"]};
}

@GET("/api/events")
function getEvents() {
    return {"sse": true};
}

25.6.2 Handler POST

@POST("/submit")
function handleSubmit(body) {
    print("Name: " + body.name);
    print("Email: " + body.email);
    return {
        "status": 200,
        "body": "<html><body><h1>Thank You!</h1></body></html>"
    };
}

25.7 Redirect con RedirectTo

Usa redirect(location, status?) per risposte di redirect esplicite, oppure l'alias legacy RedirectTo(location) quando migri codice esistente.

@POST("/login")
function handleLogin(body) {
    if (body.username == "admin" && body.password == "secret") {
        return redirect("/dashboard");
    }
    return redirect("/login?error=invalid");
}

@PAGE("/old-page")
function oldPage() {
    return redirect("/new-page", 302);
}

Per le app HTML in produzione, preferisci hashing delle password + JWT in un cookie firmato invece di controlli in chiaro. Vedi Examples/Web/auth_cookie_login.malda e gli helper condivisi req.auth (stessa superficie di RestServer).

function requireAuth(req, res, next) {
    req.auth.authenticateCookieJwt("session", jwtSecret, cookieSecret);
    next();
}

server.use(requireAuth, { "except": ["/", "/login"] });

25.8 Helper di generazione HTML

MALDA include utility helper per HTML generato e prototipi di UI renderizzata sul server.

25.8.1 Classe HTMLCache

La classe HTMLCache memorizza l'HTML generato per ridurre il lavoro LLM ripetuto e migliorare i tempi di risposta.

var cache = new HTMLCache(cacheDirectory?, maxSize?, expirationHours?);

25.8.2 Funzione extractHTML

extractHTML(markdown) estrae HTML da code fence markdown oppure restituisce l'HTML così com'è.

var html = extractHTML(markdown);

25.8.3 Funzione markdownToHtml

markdownToHtml(markdown) converte Markdown in un fragment HTML (heading, emphasis, liste, tabelle, codice fenced e simili). I tag HTML grezzi nell'input sono disabilitati, così l'output non attendibile di un modello è più sicuro da incorporare in una pagina. Restituisce una stringa; avvolgila nel chrome del tuo documento.

var body = markdownToHtml("**Hello** and a table:\n\n| A | B |\n|---|---|\n| 1 | 2 |");
return "<html><body class='md'>" + body + "</body></html>";

25.8.4 Funzione generateUI

generateUI è un helper di convenienza per la generazione HTML guidata da prompt, con cache opzionale e un agente personalizzato.

var html = generateUI(description, cache?, agent?);

25.8.5 Funzione ui.generate

Usa ui.generate quando l'AI deve restituire un albero UI server strutturato invece di una stringa HTML.

var tree = ui.generate("Dashboard with title, filter row, and data grid", uiAgent, cache);
var envelope = ui.mountEnvelope(tree, "dashboard-session");
return envelope;

25.9 Ciclo di vita dalla richiesta al render

  1. Il browser richiede una pagina o una route gestita da @PAGE, @AIPAGE, @GET o @POST.
  2. HttpServer risolve la route e carica il contesto di richiesta necessario.
  3. L'handler restituisce HTML, un redirect, JSON, SSE o un artefatto UI generato.
  4. Il browser renderizza il documento restituito, segue il redirect oppure elabora la risposta API.

25.10 Hardening in produzione

25.11 Test e risoluzione dei problemi

Vedi anche