Pular para o conteúdo
Nesta página

Servidor HTTP e Aplicações Web

Zolo inclui um servidor HTTP nativo em std::http. Ele serve APIs, texto simples e valores View do Verniz no mesmo router.

Começo rápido com uma View

use std::http
use std::html::{document, head, title, body, h1, p, View}

fn inicio(_req) -> View {
    <document lang="pt-BR">
        <head><title>Zolo web</title></head>
        <body>
            <h1>Olá do Zolo</h1>
            <p>A rota retornou uma View.</p>
        </body>
    </document>
}

let app = http.router()
    |> http.get("/", inicio)

http.serve(3000, app)

O servidor renderiza uma View retornada e escolhe o content type HTML. Strings viram texto, maps viram JSON e nil vira resposta 204.

Router e rotas

Funções de rota no estilo pipe devolvem o router:

let app = http.router()
    |> http.get("/health", health)
    |> http.get("/users/:id", show_user)
    |> http.post("/users", create_user)
    |> http.put("/users/:id", replace_user)
    |> http.delete("/users/:id", delete_user)
    |> http.middleware(logger)
Função Papel
http.router() Cria router vazio
http.get/post/put/delete(router, path, handler) Registra rota e devolve o router
http.middleware(router, fn) Adiciona middleware
http.server() Cria builder fluente de server/router
http.serve(port, router, workers: n) Inicia o servidor

O objeto router também expõe .get, .post, .put, .delete, .patch e .use. Paths aceitam capturas :id e {id}.

Dados do request

Handlers recebem método, path, headers, body, query e capturas da rota.

fn show_user(req) {
    let id = req.params.id
    let verbose = req.query.verbose ?? "0"

    return #{
        "id": id,
        "verbose": verbose,
        "method": req.method,
    }
}

fn create_user(req) {
    let payload = req.json()
    return http.created("criado {payload.name}")
}

Use req.body para o corpo cru e req.json() para JSON.

Responses

Valor Resultado
View HTML renderizado
str, número ou bool Texto simples
Map/table JSON
nil 204 No Content
http.response(status, body, headers) Resposta explícita
http.ok(body) / http.created(body) Helpers 200 / 201
http.no_content() Helper 204
http.bad_request(body) / http.not_found(body) Helpers 400 / 404
http.redirect(url) 302 com Location
http.html(body) Resposta HTML explícita

Prefira retornar View diretamente quando o body já é conteúdo Verniz.

Middleware e workers

Middleware recebe req e next:

fn logger(req, next) {
    print("[{req.method}] {req.path}")
    return next(req)
}

Passe workers: a http.serve para concorrência de produção. Cada worker repete a inicialização top-level; coloque startup do processo em on boot e setup por worker em on worker.

Durante zolo dev, o modo web usa uma VM viva para trocar source in-place.

Efeitos de request e cookies

std::web envolve rotas de std::http com os efeitos Request e Cookies. Funções profundas acessam o request ou gravam cookie sem passar req por toda a árvore.

use std::web

fn inicio(_req) with Request -> str {
    return "path: {perform Request::path()}"
}

let app = web.router() |> web.get("/", inicio)
web.serve(3000, app)

Cookies seguros são cifrados por padrão com Cookie.new; construtores signed e public tornam a escolha mais fraca explícita. Configure ZOLO_SECRET_KEY antes de produção. A camada de efeitos/cookies de std::web ainda é VM-only; o servidor HTTP e Verniz também rodam em LLVM e Cranelift.

Desenvolvimento ao vivo

zolo dev src/main.zolo

Ao alcançar http.serve, a CLI liga modo web automaticamente. Saves válidos trocam a VM viva, notificam abas por SSE, revalidam a rota e fazem morph do DOM. Erros mantêm o último app bom servindo e aparecem no overlay do navegador.

Continue em Desenvolvimento Web e Fluxo de Desenvolvimento.

Buscar no Zolo

9 resultados

enpt-br