Documentation
¶
Overview ¶
Package trilha is a file-based web framework for Go: pages, layouts, API routes and middleware are discovered from the app/ directory tree by the trilha CLI, which generates a typed registration file; this package is the runtime those generated files call into.
Index ¶
- Constants
- Variables
- func CSRFInput(c *Ctx) h.Node
- func CompileErrorPage(output string) string
- func Errorf(code int, format string, a ...any) error
- func Fatal(err error)
- func NonceAttr(c *Ctx) h.Node
- func PublicFS(embedded fs.FS, dir string) fs.FS
- func Redirect(url string) error
- func RedirectCode(url string, code int) error
- func Run(a *App)
- type App
- func (a *App) AddExportPath(paths ...string)
- func (a *App) BasePath() string
- func (a *App) Config() *Config
- func (a *App) Env() Env
- func (a *App) Export(dir string) error
- func (a *App) ExportPaths() []string
- func (a *App) Handler() http.Handler
- func (a *App) ListenAndServe() error
- func (a *App) Logger() *slog.Logger
- func (a *App) OnShutdown(fn func(*App) error)
- func (a *App) Register(r Route)
- func (a *App) Routes() map[string][]string
- func (a *App) Security() *Security
- func (a *App) SetErrorPage(e ErrorPageFunc)
- func (a *App) SetNotFound(p PageFunc)
- func (a *App) SetRootLayout(l LayoutFunc)
- func (a *App) Values() map[string]any
- type Config
- type Ctx
- func (c *Ctx) App() *App
- func (c *Ctx) Base() string
- func (c *Ctx) BindJSON(v any) error
- func (c *Ctx) CSRFToken() string
- func (c *Ctx) ClearCookie(name string)
- func (c *Ctx) ClientIP() string
- func (c *Ctx) Context() context.Context
- func (c *Ctx) Cookie(name string) (*http.Cookie, error)
- func (c *Ctx) Env() Env
- func (c *Ctx) Form(name string) string
- func (c *Ctx) FormErr() error
- func (c *Ctx) Get(key string) any
- func (c *Ctx) HTML(code int, n h.Node) error
- func (c *Ctx) Header(k, v string)
- func (c *Ctx) JSON(code int, v any) error
- func (c *Ctx) NoWriteDeadline() error
- func (c *Ctx) Nonce() string
- func (c *Ctx) Param(name string) string
- func (c *Ctx) Query(name string) string
- func (c *Ctx) Redirect(url string) error
- func (c *Ctx) Request() *http.Request
- func (c *Ctx) RequestID() string
- func (c *Ctx) Set(key string, v any)
- func (c *Ctx) SetContext(ctx context.Context)
- func (c *Ctx) SetCookie(ck *http.Cookie)
- func (c *Ctx) SetRequest(r *http.Request)
- func (c *Ctx) SetSigned(name, value string, ttl time.Duration) error
- func (c *Ctx) SetTitle(t string)
- func (c *Ctx) Signed(name string) (value string, ok bool)
- func (c *Ctx) Status(code int)
- func (c *Ctx) Stream() *Stream
- func (c *Ctx) Text(code int, s string) error
- func (c *Ctx) Title() string
- func (c *Ctx) Writer() http.ResponseWriter
- func (c *Ctx) Written() bool
- type Env
- type ErrorPageFunc
- type HTTPError
- type HandlerFunc
- type LayoutFunc
- type MiddlewareFunc
- type Next
- type PageFunc
- type RateLimit
- type RedirectError
- type Route
- type RouteKind
- type Security
- type SecurityEvent
- type Signer
- type Stream
- type Timeouts
Constants ¶
const CSRFCookie = "trilha_csrf"
CSRFCookie is the name of the double-submit cookie.
const CSRFField = "_csrf"
CSRFField is the hidden form field name.
const CSRFHeader = "X-CSRF-Token"
CSRFHeader is the header accepted instead of the form field.
const MinSecretLen = 32
MinSecretLen is the minimum accepted secret size in bytes.
const NoTimeout time.Duration = -1
NoTimeout disables a Timeouts field (becomes 0 in http.Server).
const Off = "off"
Off disables a security header when assigned to its field.
Variables ¶
var ErrNoSecret = errors.New("trilha: TRILHA_SECRET não definido; cookies assinados indisponíveis")
ErrNoSecret is returned by SetSigned when no secret is configured.
var ErrNotFound = errors.New("trilha: not found")
ErrNotFound makes the framework respond with 404 using the app's not-found page (HTML routes) or a JSON error (API routes).
var ErrRateLimited = &HTTPError{Code: http.StatusTooManyRequests, Message: "too many requests"}
ErrRateLimited is the 429 error; handlers may return it themselves.
Functions ¶
func CSRFInput ¶
CSRFInput renders the hidden input for forms: h.Form(..., trilha.CSRFInput(c), ...).
func CompileErrorPage ¶
compileErrorPage is used by the CLI dev server; exported for reuse.
func Fatal ¶
func Fatal(err error)
Fatal logs a fatal error and exits, ignoring the normal server-closed error.
func NonceAttr ¶ added in v0.2.0
NonceAttr renders the nonce attribute for an inline <script>: h.Script(trilha.NonceAttr(c), h.Raw(js)).
func PublicFS ¶
PublicFS returns the static file system for the public directory: the embedded copy in prod, the on-disk directory in dev (so edits show up without a rebuild).
func RedirectCode ¶
RedirectCode returns a redirect error with a custom 3xx status.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is a configured Trilha application.
func (*App) AddExportPath ¶ added in v0.2.0
AddExportPath registers extra paths to render on Export, typically pages under dynamic routes (e.g. "/blog/ola"). Call it from Setup.
func (*App) BasePath ¶ added in v0.2.0
BasePath returns the URL prefix the app is served under ("" or "/docs").
func (*App) Config ¶ added in v0.2.0
Config returns the live configuration for adjustment in Setup. Every field may be changed there: per-request fields (Security, Public, MaxBodyBytes, CSRFForAPI, BasePath, OnSecurityEvent, Static*) are read on each request; derived fields (Logger, Secret/PreviousSecret, RateLimit, TrustedProxies) are reapplied when serving starts (ListenAndServe, Handler, Export); Addr and Timeouts are read by ListenAndServe. To build the Config before New, export func Config(cfg *trilha.Config) in app/setup.go.
func (*App) Export ¶ added in v0.2.0
Export renders the app as a static site into dir: one index.html per path, 404.html from the not-found page, and a copy of public/. The directory is emptied first, but only if Export created it before.
func (*App) ExportPaths ¶ added in v0.2.0
ExportPaths lists what Export will render: static page routes plus the paths added with AddExportPath, sorted and deduplicated.
func (*App) Handler ¶
Handler returns the root http.Handler (useful for tests and embedding). Like ListenAndServe, it reapplies Config changes made in Setup.
func (*App) ListenAndServe ¶
ListenAndServe serves until SIGINT/SIGTERM, then shuts down gracefully.
func (*App) OnShutdown ¶ added in v0.3.0
OnShutdown registers fn to run after the server stopped accepting requests (close pools, flush logs). Hooks run in reverse registration order; setup.go may export func Shutdown(a *trilha.App) error, which the generated main registers for you.
func (*App) Security ¶ added in v0.2.0
Security returns the security settings for adjustment in Setup.
func (*App) SetErrorPage ¶
func (a *App) SetErrorPage(e ErrorPageFunc)
SetErrorPage sets the page rendered on 500 (app/error.go).
func (*App) SetNotFound ¶
SetNotFound sets the page rendered on 404 (app/not_found.go).
func (*App) SetRootLayout ¶
func (a *App) SetRootLayout(l LayoutFunc)
SetRootLayout sets the layout used by the not-found and error pages.
type Config ¶
type Config struct {
// Addr is the listen address (default ":3000").
Addr string
// Env selects dev (stack traces, live reload, no static cache) or prod.
Env Env
// MaxBodyBytes limits request bodies (default 1 MiB).
MaxBodyBytes int64
// Logger receives structured request logs (default slog.Default()).
Logger *slog.Logger
// Public serves static files at the root. nil disables static files.
Public fs.FS
// CSRFForAPI also enforces CSRF tokens on route.go handlers.
CSRFForAPI bool
// BasePath is the URL prefix the app is served under (e.g. "/docs" on
// GitHub Pages). Read it with Ctx.Base when building links.
BasePath string
// Security tunes the hardening headers (zero value = defaults).
Security Security
// TrustedProxies lists CIDRs whose X-Forwarded-For/Proto are honoured.
TrustedProxies []string
// RateLimit enables a global per-client limit (zero = off).
RateLimit RateLimit
// Secret signs cookies (TRILHA_SECRET); PreviousSecret still verifies.
Secret, PreviousSecret []byte
// Timeouts protect the server from slow clients.
Timeouts Timeouts
// StaticCacheControl replaces the production Cache-Control of files in
// Public (default "public, max-age=3600"; dev always sends no-cache).
StaticCacheControl string
// StaticHeaders runs for every file served from Public, after the
// defaults, and may set any header (immutable for hashed assets, CORP...).
StaticHeaders func(name string, hdr http.Header)
// OnSecurityEvent is called for blocked requests (CSRF, 401/403, 413, 429, panic).
OnSecurityEvent func(SecurityEvent)
// DevReload controls the live-reload script injected in Dev pages; Off
// disables it (snapshot tests, HTML diffs). TRILHA_DEV_RELOAD=off does the same.
DevReload string
}
Config configures an App.
func ConfigFromEnv ¶
func ConfigFromEnv() Config
ConfigFromEnv builds a Config from ADDR/PORT and TRILHA_ENV.
type Ctx ¶
type Ctx struct {
// contains filtered or unexported fields
}
Ctx wraps one request/response pair. It is created per request and is not safe for use from other goroutines after the handler returns.
func (*Ctx) Base ¶ added in v0.2.0
Base returns the app's base path for building links: c.Base()+"/aprender".
func (*Ctx) BindJSON ¶
BindJSON decodes the request body into v. Returns an HTTPError 400 on malformed JSON and 413 when the body exceeds the limit.
func (*Ctx) CSRFToken ¶
CSRFToken returns the request's CSRF token, creating the cookie on first use. Put it in forms with CSRFInput or send it in the X-CSRF-Token header.
func (*Ctx) ClearCookie ¶ added in v0.2.0
ClearCookie expires a cookie.
func (*Ctx) ClientIP ¶ added in v0.2.0
ClientIP returns the client address: RemoteAddr, or the right-most untrusted entry of X-Forwarded-For when the peer is a trusted proxy.
func (*Ctx) Form ¶
Form returns a form field (POST body or query string). Returns "" if the form cannot be parsed; use FormErr to distinguish.
func (*Ctx) NoWriteDeadline ¶ added in v0.2.0
NoWriteDeadline disables the server write timeout for this response; call it before streaming (SSE, long downloads).
func (*Ctx) SetContext ¶ added in v0.2.0
SetContext replaces the request context, so a middleware can pass values to code that only receives *http.Request (templates, stdlib helpers).
func (*Ctx) SetRequest ¶ added in v0.2.0
SetRequest replaces the request (rewritten URL, wrapped body...). Values already read from the old request (form, request id) are kept.
func (*Ctx) SetSigned ¶ added in v0.2.0
SetSigned stores a tamper-proof cookie (HttpOnly, SameSite=Lax, Secure on HTTPS) that expires after ttl. Returns ErrNoSecret without a secret.
func (*Ctx) Signed ¶ added in v0.2.0
Signed reads a cookie written by SetSigned; ok is false when missing, tampered or expired.
func (*Ctx) Stream ¶ added in v0.2.0
Stream switches the response to text/event-stream, disables the write deadline and returns a writer for events. Use it from a GET route:
func GET(c *trilha.Ctx) error {
s := c.Stream()
for chunk := range chunks {
if err := s.Send("delta", chunk); err != nil { return err }
}
return s.Send("done", "")
}
Compression is skipped for streams, and each event is flushed right away.
func (*Ctx) Writer ¶
func (c *Ctx) Writer() http.ResponseWriter
Writer returns the underlying http.ResponseWriter.
type ErrorPageFunc ¶
ErrorPageFunc renders the 500 page (error.go: Error).
type HandlerFunc ¶
HandlerFunc handles an API method or a form submission.
type LayoutFunc ¶
LayoutFunc wraps rendered children (layout.go: Layout).
type MiddlewareFunc ¶
MiddlewareFunc intercepts a subtree (middleware.go: Middleware).
func Limit ¶ added in v0.2.0
func Limit(rps float64, burst int) MiddlewareFunc
Limit returns a middleware applying its own per-client limit to a subtree: put `var limit = trilha.Limit(2, 5)` in middleware.go and call it.
type RateLimit ¶ added in v0.2.0
type RateLimit struct {
// RPS is the sustained requests per second per client.
RPS float64
// Burst is the bucket size (requests allowed at once).
Burst int
}
RateLimit configures the per-client token bucket. Zero disables it.
type RedirectError ¶
RedirectError is returned by handlers to redirect the client.
func (*RedirectError) Error ¶
func (e *RedirectError) Error() string
type Route ¶
type Route struct {
// Pattern is the path pattern, e.g. "/blog/{slug}" or "/docs/{path...}".
Pattern string
// Page renders GET for page routes; nil for API routes.
Page PageFunc
// Methods maps HTTP methods to handlers (route.go, or form methods in page.go).
Methods map[string]HandlerFunc
// Layouts wrap the page, innermost first.
Layouts []LayoutFunc
// Middlewares run before the handler, outermost first.
Middlewares []MiddlewareFunc
// Kind decides how errors are rendered (HTML page or JSON) and whether
// CSRF applies. KindAuto: page.go routes are pages; route.go routes are
// APIs, except that a browser navigation (Accept: text/html, outside
// /api/) gets HTML error pages. route.go may export `var Kind = trilha.KindPage`.
Kind RouteKind
}
Route is one entry produced by the generator for App.Register.
type RouteKind ¶ added in v0.3.0
type RouteKind int
RouteKind is the error/CSRF behaviour of a Route; see Route.Kind.
type Security ¶ added in v0.2.0
type Security struct {
// CSP is the Content-Security-Policy. Empty = default policy with a
// per-request nonce for scripts; the text may contain {nonce}.
CSP string
// CSPExtra adds sources to directives of the default policy, e.g.
// {"style-src": {"https://fonts.googleapis.com"}}.
CSPExtra map[string][]string
// HSTS is sent only over HTTPS (TLS or a trusted proxy saying so).
HSTS string
// PermissionsPolicy restricts browser features.
PermissionsPolicy string
// COOP is Cross-Origin-Opener-Policy.
COOP string
// FrameOptions is X-Frame-Options.
FrameOptions string
// Referrer is Referrer-Policy.
Referrer string
}
Security configures the hardening headers sent with every response. The zero value means "defaults"; set a field to Off to drop that header.
type SecurityEvent ¶ added in v0.2.0
type SecurityEvent struct {
// Kind is one of csrf, auth, body, rate, panic.
Kind string
Status int
Method string
Path string
IP string
RequestID string
}
SecurityEvent describes a request the framework blocked or flagged.
type Signer ¶ added in v0.2.0
type Signer struct {
// contains filtered or unexported fields
}
Signer signs and verifies values with HMAC-SHA256. The first key signs; every key verifies, so a previous key can be kept during rotation.
func NewSigner ¶ added in v0.2.0
NewSigner creates a signer; the first key signs, the rest only verify.
type Stream ¶ added in v0.2.0
type Stream struct {
// contains filtered or unexported fields
}
Stream is a Server-Sent Events writer returned by Ctx.Stream.
func (*Stream) Comment ¶ added in v0.2.0
Comment sends a comment line (keeps proxies from timing out the stream).
func (*Stream) Done ¶ added in v0.2.0
func (s *Stream) Done() <-chan struct{}
Done reports when the client went away.
func (*Stream) Flush ¶ added in v0.2.0
func (s *Stream) Flush()
Flush pushes buffered bytes to the client.
type Timeouts ¶ added in v0.2.0
type Timeouts struct {
ReadHeader time.Duration // 10s
Read time.Duration // 30s
Write time.Duration // 60s (use Ctx.NoWriteDeadline for streams)
Idle time.Duration // 120s
MaxHeaderBytes int // 64 KiB
// Shutdown is how long ListenAndServe waits for in-flight requests after
// SIGINT/SIGTERM before closing (5s).
Shutdown time.Duration
}
Timeouts are the http.Server limits. Zero fields get defaults; NoTimeout disables one (large uploads, long polls). Write applies to the whole response: streams should call Ctx.Stream or Ctx.NoWriteDeadline instead of disabling it globally.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package ai talks to chat-completion APIs that follow the OpenAI protocol (OpenAI, Azure, Ollama, LM Studio, Groq, OpenRouter, vLLM...) and builds agents on top of them: tools, handoffs, parallel and chained agents.
|
Package ai talks to chat-completion APIs that follow the OpenAI protocol (OpenAI, Azure, Ollama, LM Studio, Groq, OpenRouter, vLLM...) and builds agents on top of them: tools, handoffs, parallel and chained agents. |
|
mcp
Package mcp implements the Model Context Protocol (JSON-RPC 2.0 over stdio or Streamable HTTP) as a client, to bring external tools into an ai.Agent, and as a server, to expose your app's tools to MCP hosts.
|
Package mcp implements the Model Context Protocol (JSON-RPC 2.0 over stdio or Streamable HTTP) as a client, to bring external tools into an ai.Agent, and as a server, to expose your app's tools to MCP hosts. |
|
cmd
|
|
|
trilha
command
Command trilha is the CLI: new, gen, dev, build, routes.
|
Command trilha is the CLI: new, gen, dev, build, routes. |
|
examples
|
|
|
assistente
command
|
|
|
assistente/app/api/chat
Package chat streams agent runs to the browser over Server-Sent Events.
|
Package chat streams agent runs to the browser over Server-Sent Events. |
|
assistente/app/mcp
Package mcp exposes the example's tools to MCP hosts (Streamable HTTP).
|
Package mcp exposes the example's tools to MCP hosts (Streamable HTTP). |
|
assistente/internal/ferramentas
Package ferramentas holds the tools, agents and MCP server of the example.
|
Package ferramentas holds the tools, agents and MCP server of the example. |
|
blog
command
|
|
|
blog/app/api/posts
Package posts exposes the JSON API at /api/posts.
|
Package posts exposes the JSON API at /api/posts. |
|
blog/app/marketing-
Package marketing is a route group: its layout wraps /precos and /sobre without adding a URL segment (folder name ends with "-").
|
Package marketing is a route group: its layout wraps /precos and /sobre without adding a URL segment (folder name ends with "-"). |
|
blog/app/painel-
Package painel is a route group for the app area (/painel, /relatorio).
|
Package painel is a route group for the app area (/painel, /relatorio). |
|
blog/app/painel-/relatorio
Package relatorio renders a page from an html/template file instead of the h DSL, using the tmpl adapter.
|
Package relatorio renders a page from an html/template file instead of the h DSL, using the tmpl adapter. |
|
blog/internal/posts
Package posts is an in-memory post store for the example app.
|
Package posts is an in-memory post store for the example app. |
|
Package h is a small, dependency-free HTML DSL: every element, attribute and piece of text is a Node that knows how to render itself to an io.Writer.
|
Package h is a small, dependency-free HTML DSL: every element, attribute and piece of text is a Node that knows how to render itself to an io.Writer. |
|
internal
|
|
|
dev
Package dev implements `trilha dev`: a polling file watcher, a builder and a supervisor that runs the app behind a reverse proxy with live reload.
|
Package dev implements `trilha dev`: a polling file watcher, a builder and a supervisor that runs the app behind a reverse proxy with live reload. |
|
gen
Package gen turns a scan.Result into the source of trilha_gen.go.
|
Package gen turns a scan.Result into the source of trilha_gen.go. |
|
scaffold
Package scaffold writes a new project from embedded templates.
|
Package scaffold writes a new project from embedded templates. |
|
scan
Package scan walks an app/ directory and turns its file conventions into a list of routes, validating them along the way.
|
Package scan walks an app/ directory and turns its file conventions into a list of routes, validating them along the way. |
|
app
Package app is the documentation site of Trilha, built with Trilha.
|
Package app is the documentation site of Trilha, built with Trilha. |
|
internal/demos
Package demos holds the "código → resultado" examples used by the home page and by chapters.
|
Package demos holds the "código → resultado" examples used by the home page and by chapters. |
|
internal/docs
Package docs loads the Markdown content of the documentation site, builds the navigation and renders pages.
|
Package docs loads the Markdown content of the documentation site, builds the navigation and renders pages. |
|
internal/md
Package md is a deliberately small Markdown-to-HTML converter for the documentation site: headings with ids, paragraphs, lists, fenced code (with Go highlighting), tables, blockquotes, callouts (:::nome), inline code, emphasis and links.
|
Package md is a deliberately small Markdown-to-HTML converter for the documentation site: headings with ids, paragraphs, lists, fenced code (with Go highlighting), tables, blockquotes, callouts (:::nome), inline code, emphasis and links. |
|
internal/ui
Package ui holds the shared building blocks of the documentation site: the document shell, sidebar, table of contents and helpers.
|
Package ui holds the shared building blocks of the documentation site: the document shell, sidebar, table of contents and helpers. |
|
Package tmpl adapts html/template to the h.Node pipeline, for developers who prefer template files over the Go DSL.
|
Package tmpl adapts html/template to the h.Node pipeline, for developers who prefer template files over the Go DSL. |