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) Asset(p string) string
- func (a *App) BasePath() string
- func (a *App) Check(name string, fn func(context.Context) error)
- 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) HealthReport(ctx context.Context) HealthReport
- func (a *App) ListenAndServe() error
- func (a *App) Logger() *slog.Logger
- func (a *App) Metrics() *Metrics
- 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 CheckResult
- type Config
- type Counter
- type Ctx
- func (c *Ctx) App() *App
- func (c *Ctx) Asset(p string) string
- func (c *Ctx) Base() string
- func (c *Ctx) Bind(v any) error
- 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) Fragment() string
- 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) Island(src string, props any, children ...h.Node) h.Node
- func (c *Ctx) JSON(code int, v any) error
- func (c *Ctx) Log() *slog.Logger
- 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) Render(code int, node h.Node) 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) TraceID() string
- func (c *Ctx) Writer() http.ResponseWriter
- func (c *Ctx) Written() bool
- type Env
- type ErrorPageFunc
- type FieldErrors
- type Gauge
- type HTTPError
- type HandlerFunc
- type HealthReport
- type Histogram
- type LayoutFunc
- type Metrics
- type MiddlewareFunc
- type Next
- type Observability
- type PageFunc
- type RateLimit
- type RedirectError
- type Route
- type RouteKind
- type Security
- type SecurityEvent
- type Signer
- type Stream
- type Timeouts
Constants ¶
const ( // StatusPass means every check passed. StatusPass = "pass" // StatusFail means at least one check failed. StatusFail = "fail" )
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 BindInvalid = "invalid value"
BindInvalid is the FieldErrors message Bind records when a value cannot be converted to the field's type. Change it to localise.
var ErrNoSecret = errors.New("trilha: TRILHA_SECRET not set; signed cookies unavailable")
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) Asset ¶ added in v0.8.0
Asset returns the URL of a file in Config.Public carrying a version derived from its content:
h.Link(h.Rel("stylesheet"), h.Href(c.Asset("/site.css")))
// → /site.css?v=8f3a1c92
The point is the address changing when the content changes: a CDN or browser holding the old file is asked for a URL it has never seen, so a deploy cannot leave someone with new HTML and old CSS. It also makes a long StaticCacheControl safe.
BasePath is applied, so Asset replaces Base()+path. An unknown file returns the path unchanged (with a warning in the log) rather than breaking the page.
func (*App) BasePath ¶ added in v0.2.0
BasePath returns the URL prefix the app is served under ("" or "/docs").
func (*App) Check ¶ added in v0.6.0
Check registers a readiness check: a dependency the app needs in order to serve (database, cache, queue). It runs on /_trilha/health and /_trilha/health/ready, with the configured timeout, and its result is cached for Observability.CacheFor. Liveness never runs checks, so a dependency blinking does not restart the process.
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) HealthReport ¶ added in v0.6.0
func (a *App) HealthReport(ctx context.Context) HealthReport
HealthReport runs the readiness checks and returns the full report, including error messages. Use it from your own code (a status page, a startup gate); the HTTP endpoint decides what to reveal.
func (*App) ListenAndServe ¶
ListenAndServe serves until SIGINT/SIGTERM, then shuts down gracefully.
func (*App) Metrics ¶ added in v0.6.0
Metrics returns the process metric registry. It always exists; set Config.Observability.Metrics to expose it over HTTP.
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 CheckResult ¶ added in v0.6.0
type CheckResult struct {
Name string `json:"name"`
Status string `json:"status"`
DurationMS float64 `json:"duration_ms"`
Error string `json:"error,omitempty"`
}
CheckResult is the outcome of one readiness check. Error is only ever sent to an authorized client; anonymous callers see the status alone.
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
// Mounts serve static trees at URL prefixes, for the app whose disk tree
// is not shaped like its URL tree. They match before Public, longest
// prefix first, and fall through to it when the file is not there.
Mounts map[string]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)
// LogRequest decides, with the response already written, whether a
// request enters the access log. nil logs every one of them.
LogRequest func(c *Ctx, status int, dur time.Duration) bool
// 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
// Observability configures the health probes, the metrics endpoint and
// what each of them reveals.
Observability Observability
}
Config configures an App.
func ConfigFromEnv ¶
func ConfigFromEnv() Config
ConfigFromEnv builds a Config from ADDR/PORT and TRILHA_ENV.
type Counter ¶ added in v0.6.0
type Counter struct {
// contains filtered or unexported fields
}
Counter only ever grows: requests served, errors, events.
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) Bind ¶ added in v0.5.0
Bind fills a struct from the request: JSON when the Content-Type is application/json (see BindJSON), otherwise form fields and query string. Fields are matched by the `form:"name"` tag (or the field name). Supported types: string, []string, bool (checkbox: on/true/1), int, int64, float64, time.Time (2006-01-02 or 2006-01-02T15:04) and pointers to them (nil when absent). A nested struct is flattened: its fields are read with the struct's tag as prefix (`Cobranca Endereco `+"`"+`form:"cob_"`+"`"+` reads cob_cep...), or with no prefix when it has no tag. Values that fail to convert are reported as FieldErrors, after every field was tried, so all messages reach the user at once.
var in struct {
Nome string `form:"nome"`
Idade int `form:"idade"`
Ativo bool `form:"ativo"`
}
if err := c.Bind(&in); err != nil { return err }
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) Fragment ¶ added in v0.10.0
Fragment returns the part of the page this request asked for, or "" on a normal navigation. It is the whole protocol: the same route serves the page and the piece, and decides what to return.
func Page(c *trilha.Ctx) (h.Node, error) {
lista := listaDe(c)
if c.Fragment() == "lista" {
return lista, nil // sem layouts
}
return h.Div(busca(), lista), nil
}
A fragment response carries no layout, no document envelope and no dev script; every HTML response gets Vary: Trilha-Fragment so a cache never serves one in place of the other.
func (*Ctx) Island ¶ added in v0.13.0
Island renders an interactive region of a page that stays static: the server sends the fallback HTML, and a module in public/ takes over on the client. There is no global hydration and no bundler — src is a file in public/, addressed through Asset so it gets the content hash:
c.Island("/editor.js", map[string]any{"wpm": 200},
h.Class("editor"), ui.Textarea(h.Name("corpo")))
The module's default export is the mount function, called once with the element and the props already parsed:
export default function (el, props) { ... }
props is anything encoding/json can serialize, or nil. What the server sends is data, never markup: it is escaped as an attribute and read back with JSON.parse. The children are the fallback, so the page works with the script blocked, failing to load, or still on its way.
func (*Ctx) Log ¶ added in v0.6.0
Log returns a logger already carrying request_id and, when present, trace_id, so every line of one request can be found together (NIST SP 800-53 AU-3).
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) Render ¶ added in v0.5.0
Render writes node as a page with the route's layouts applied (innermost first), like GET does. Use it in POST handlers to answer a form with validation errors inside the same layouts:
if errs := validate(in); errs.Any() {
return c.Render(422, formulario(c, in, errs))
}
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) TraceID ¶ added in v0.6.0
TraceID returns the trace identifier the caller propagated in the traceparent header, or "" when it is absent or malformed. Trilha only carries the identifier into the logs; it does not sample or export spans.
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 FieldErrors ¶ added in v0.5.0
FieldErrors collects validation messages by form field. Returned from a handler it answers 422: JSON with a "fields" object on API routes, or the error page on pages — though a form usually re-renders itself with Ctx.Render and shows each message next to its field.
func (FieldErrors) Add ¶ added in v0.5.0
func (e FieldErrors) Add(field, msg string)
Add records a message for field (the first one wins).
func (FieldErrors) Any ¶ added in v0.5.0
func (e FieldErrors) Any() bool
Any reports whether there is at least one error.
func (FieldErrors) Error ¶ added in v0.5.0
func (e FieldErrors) Error() string
Error joins the messages, sorted by field, for logs and API responses.
func (FieldErrors) Get ¶ added in v0.5.0
func (e FieldErrors) Get(field string) string
Get returns the message for field, or "".
func (FieldErrors) Has ¶ added in v0.5.0
func (e FieldErrors) Has(field string) bool
Has reports whether field has an error.
func (FieldErrors) OrNil ¶ added in v0.5.0
func (e FieldErrors) OrNil() error
OrNil returns e as an error, or nil when empty, for `return errs.OrNil()`.
type Gauge ¶ added in v0.6.0
type Gauge struct {
// contains filtered or unexported fields
}
Gauge goes up and down: queue depth, connections in use.
type HandlerFunc ¶
HandlerFunc handles an API method or a form submission.
type HealthReport ¶ added in v0.6.0
type HealthReport struct {
Status string `json:"status"`
Checks []CheckResult `json:"checks,omitempty"`
UptimeSeconds float64 `json:"uptime_seconds,omitempty"`
}
HealthReport is the readiness of the application.
type Histogram ¶ added in v0.6.0
type Histogram struct {
// contains filtered or unexported fields
}
Histogram counts observations per bucket: durations, sizes.
type LayoutFunc ¶
LayoutFunc wraps rendered children (layout.go: Layout).
type Metrics ¶ added in v0.6.0
type Metrics struct {
// MaxSeries caps the number of label combinations per metric (default
// 1000). Extra combinations are folded into a single "other" series.
MaxSeries int
// contains filtered or unexported fields
}
Metrics is the process metric registry, exposed in the Prometheus text format. Get it with App.Metrics; it exists even when no endpoint serves it.
func (*Metrics) Counter ¶ added in v0.6.0
Counter returns (creating on first use) a counter. labels declares the dimension names; bind the values with With. Invalid names panic: it is a programming error, caught on the first run.
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 Observability ¶ added in v0.6.0
type Observability struct {
// Health is the base path of the probes (default "/_trilha/health",
// with /live and /ready under it). Off removes them.
Health string
// Metrics is the path of the Prometheus endpoint. Empty (the default)
// means no endpoint and no request instrumentation.
Metrics string
// Token authorizes the detailed health and the metrics
// (Authorization: Bearer ...). It must have at least 32 bytes; shorter
// tokens never authorize anything. Read from TRILHA_OBS_TOKEN.
Token string
// Trusted lists CIDRs (or plain IPs) that skip the token, for a scraper
// on a private network. "0.0.0.0/0" plus "::/0" opens it to everyone:
// only do that when something in front already restricts access.
Trusted []string
// Details is Off to never reveal check names and errors, even to an
// authorized client. Empty means dev shows them and prod requires
// authorization.
Details string
// Timeout is the deadline of each readiness check (default 2s).
// NoTimeout waits forever (not recommended: the probe holds a connection).
Timeout time.Duration
// CacheFor is how long a readiness result is reused (default 1s), so a
// flood of probes cannot amplify into a flood of database queries.
// NoTimeout disables the cache.
CacheFor time.Duration
}
Observability configures the health, metrics and tracing surface. The zero value serves the health probes and nothing else: metrics have to be turned on explicitly, and outside dev the detailed health needs authorization (NIST SP 800-53 AU-9, OWASP API Security 2023 API8).
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. |
|
Package auth adds OpenID Connect login, signed sessions and role checks to a Trilha app, using only the standard library.
|
Package auth adds OpenID Connect login, signed sessions and role checks to a Trilha app, using only the standard library. |
|
cmd
|
|
|
trilha
command
Command trilha is the CLI: new, gen, dev, build, routes, export, audit, ui.
|
Command trilha is the CLI: new, gen, dev, build, routes, export, audit, ui. |
|
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/icones
Package icones embute os ícones do site.
|
Package icones embute os ícones do site. |
|
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. |
|
cadastro
command
|
|
|
cadastro/app/api/cidades
Package cidades serves the dependent select: GET /api/cidades?uf=SP.
|
Package cidades serves the dependent select: GET /api/cidades?uf=SP. |
|
cadastro/internal/clientes
Package clientes holds the domain of the example: the form model, its validation rules and an in-memory store.
|
Package clientes holds the domain of the example: the form model, its validation rules and an in-memory store. |
|
orcamento
command
|
|
|
orcamento/app/api/relatorio.csv
Package relatoriocsv exports the month as CSV at /api/relatorio.csv?mes=.
|
Package relatoriocsv exports the month as CSV at /api/relatorio.csv?mes=. |
|
orcamento/app/lancamentos
Package lancamentos has the standalone entry page (works without JS) and the POST every entry form submits to (dialog included).
|
Package lancamentos has the standalone entry page (works without JS) and the POST every entry form submits to (dialog included). |
|
orcamento/internal/componentes
Package componentes holds the reusable, nested UI pieces of the budget example.
|
Package componentes holds the reusable, nested UI pieces of the budget example. |
|
orcamento/internal/plano
Package plano is the domain of the budget example: a chart of accounts (tree), monthly budgets on analytic accounts, and entries.
|
Package plano is the domain of the budget example: a chart of accounts (tree), monthly budgets on analytic accounts, and entries. |
|
sso
command
|
|
|
sso/app/api
Package api agrupa as rotas de API.
|
Package api agrupa as rotas de API. |
|
sso/app/api/eu
Package eu devolve a sessão como JSON.
|
Package eu devolve a sessão como JSON. |
|
sso/app/entrar
Package entrar começa o login.
|
Package entrar começa o login. |
|
sso/app/entrar/retorno
Package retorno termina o login.
|
Package retorno termina o login. |
|
sso/app/painel
Package painel é a área que exige sessão.
|
Package painel é a área que exige sessão. |
|
sso/app/painel/relatorio
Package relatorio exige um papel, não só sessão.
|
Package relatorio exige um papel, não só sessão. |
|
sso/app/sair
Package sair encerra a sessão.
|
Package sair encerra a sessão. |
|
sso/internal/sso
Package sso monta o fluxo OpenID Connect a partir do ambiente e expõe funções finas para as rotas em app/.
|
Package sso monta o fluxo OpenID Connect a partir do ambiente e expõe funções finas para as rotas em 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 "code → result" examples used by the home page and by chapters.
|
Package demos holds the "code → result" examples used by the home page and by chapters. |
|
internal/docs
Package docs loads the Markdown content of the documentation site in every locale, builds the navigation and renders pages.
|
Package docs loads the Markdown content of the documentation site in every locale, builds the navigation and renders pages. |
|
internal/home
Package home renders the landing page of the site in each locale.
|
Package home renders the landing page of the site in each locale. |
|
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. |
|
Package ui is Trilha's default, customizable UI kit: typed components that render classes consumed by public/ui.css, plus a small ui.js for behavior.
|
Package ui is Trilha's default, customizable UI kit: typed components that render classes consumed by public/ui.css, plus a small ui.js for behavior. |