v0.2.0
Zinc 0.2.0
Zinc 0.2 makes the framework a clearer application layer for Go's standard HTTP stack. It keeps the small Get, JSON, and error-returning handler experience while making routing, registration, and interoperability more idiomatic.
This is an intentional pre-1.0 breaking release. See the migration guide for mechanical upgrade steps.
Cleaner route definitions
Zinc now uses Go-style brace patterns:
app.Get("/users/{id}", showUser)
app.Get("/files/{path...}", serveFile)Zinc handlers read matched values through Context.Param:
c.Param("id")Standard handlers registered with HandleHTTP or Wrap receive the same
matched values through http.Request.PathValue:
app.HandleHTTP("GET /users/{id}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, r.PathValue("id"))
}))Colon parameters, star wildcards, and regex-constrained patterns have been removed. Validate parameter formats in handlers, binders, or application code.
Minimal, typed registration
Route helpers accept only zinc.HandlerFunc and no longer return registration errors:
app.Get("/health", func(c *zinc.Context) error {
return c.String("ok")
})Invalid or conflicting routes declared in source panic during startup instead of allowing an error to be ignored. Routes loaded from configuration or plugins can use the explicit error-returning API:
if err := app.TryHandle(spec); err != nil {
return err
}The literal string handler shorthand and StringHandler have been removed.
First-class net/http
Register standard handlers directly:
app.HandleHTTP("GET /metrics", promhttp.Handler())Wrap the entire application in standard middleware:
app.UseHTTP(requestTracing, authenticateRequest)Standard middleware runs outside Zinc application, group, and route middleware. The original request, response writer, and optional interfaces such as Flusher, Hijacker, ReaderFrom, Pusher, and Unwrap are preserved.
App continues to implement http.Handler, so applications can keep using a user-owned http.Server.
Explicit context lifetime
Context.Copy has been removed. Zinc contexts are pooled and valid only while their handler is running.
Background work should extract exact values before the handler returns. Use c.Request().Context() when work shares request cancellation, or deliberately use context.WithoutCancel when standard context values must outlive it.
Behavior retained
- Handlers remain
func(*zinc.Context) error. Get,Post,c.JSON,c.String,Map, context storage, and typed getters remain.CaseSensitiveandStrictRoutingremain configurable and default tofalse.- Automatic
HEAD, automaticOPTIONS, and 405 responses remain enabled. app.Listenremains available with Zinc's server timeout defaults.- The
jobspackage remains an optional first-party package.
Performance
The new route syntax retains the pre-0.2 request-time performance of Zinc
handlers. Standard handlers populate PathValue at the native-handler boundary,
so ordinary Context.Param routes do not pay for unused interoperability work.
Both paths remain zero-allocation after warm-up.
On the final Apple M1 Pro comparison, Zinc recorded the lowest latency in 62 of 77 comparable rows against Gin, Echo, and Chi. It was fastest or within 2% of the fastest result in 63 rows. See the complete benchmark report for the environment, command, and complete results.
Breaking-change checklist
- Replace
:idwith{id}. - Replace
*pathwith{path...}. - Move regex route constraints into validation.
- Replace literal string routes with typed handlers.
- Remove error checks around source route registration.
- Use
TryHandlefor dynamically supplied routes. - Replace
Context.Copywith explicit value extraction.