Gorilla Schema
Gorilla Schema fills Go structs from HTTP form values and encodes them back into url.Values using struct tags.
Repository Health
Technical Analysis
Gorilla Schema is a small, dependency-free Go library that converts between map[string][]string (the shape of url.Values, r.PostForm, and r.MultipartForm) and Go structs. Instead of hand-writing form-parsing boilerplate in every HTTP handler, you instantiate a single Decoder (or Encoder) and reuse it across requests — it caches struct metadata internally so repeated calls avoid re-walking reflection on every request.
The library supports custom field names and exclusions via a schema struct tag, required-field validation, per-field default values, dotted-path notation for nested structs (Phone.Number), indexed notation for slices of structs (Phones.0.Label), and a RegisterConverter/RegisterEncoder extension point for custom types that don’t implement encoding.TextUnmarshaler. It’s part of the Gorilla web toolkit, the same family as gorilla/mux and gorilla/websocket, and is commonly paired with net/http handlers that need to decode form submissions into typed structs without pulling in a full validation framework.
What You Get
- A
Decodertype that fills a struct frommap[string][]stringviaDecode(dst, src), safe to share as a package-level singleton - A symmetric
Encodertype that converts a struct back intomap[string][]stringviaEncode(src, dst) - Struct-tag driven field mapping (
schema:"name"), field exclusion (schema:"-"), required-field enforcement, and default values viaschema:"field,default:value" - Dotted-path and indexed notation for decoding/encoding nested structs and slices of structs directly from flat form keys
RegisterConverter/RegisterEncoderhooks for wiring in custom types beyond the built-in bool/int/float/string/uint variants- Typed, structured errors (
MultiError,ConversionError,UnknownKeyError,EmptyFieldError) instead of opaque strings
Common Use Cases
- Decoding
r.PostForm/r.MultipartFormfrom anet/httphandler directly into a typed request struct - Populating query-parameter structs from
r.URL.Query()in REST-style Go APIs - Round-tripping structs to
url.Valueswhen building outbound HTTP client requests - Validating required form fields without adopting a separate validation library
Under The Hood
Architecture
The library is a single flat schema package split into four files with no framework or DI layer: cache.go maintains a sync.RWMutex-guarded map[reflect.Type]*structInfo that stores each struct’s field aliases, required/default tag options, and any registered converter, built once per type and reused across every subsequent Decode/Encode call; decoder.go and encoder.go are deliberately symmetric — Decoder.Decode walks the incoming map’s keys, resolves each dotted/indexed path via cache.parsePath into a chain of reflect.Value field lookups (recursing for slices of structs, disambiguated by a numeric path segment), and falls back through encoding.TextUnmarshaler then the built-in converters in converter.go, while Encoder.Encode walks a struct’s fields via reflection and rebuilds the same flat map shape, recursing into embedded and nested structs. The riskiest shared surface is cache.parsePath/cache.create, since every decode and encode call depends on it being correct for arbitrary struct shapes.
Tech Stack
Zero external dependencies — go.mod declares only the module path and go 1.20; everything is built on reflect, encoding, strconv, strings, sync, errors, and fmt from the standard library. It has no database or web-framework integration of its own; it’s designed to sit inside net/http handlers and works directly against url.Values-shaped maps such as r.PostForm.
Code Quality
Testing is extensive for the library’s size — 54 test functions in decoder_test.go and 14 in encoder_test.go using table-driven testing patterns, run via the Makefile’s test target with -race -cover -coverprofile=... -covermode=atomic. A dedicated GitHub Actions “Security” workflow runs gosec and govulncheck on every push and pull request across Go 1.20 and 1.21, and the Makefile wires up golangci-lint for local/CI linting. Errors are typed and structured (MultiError, ConversionError, UnknownKeyError, EmptyFieldError) rather than ad hoc strings, and naming follows idiomatic Go conventions throughout.
API Design
The public surface is two symmetric, single-purpose types — NewDecoder()/Decode() and NewEncoder()/Encode() — mirroring the ergonomics of encoding/json’s Marshal/Unmarshal and requiring no boilerplate beyond instantiating one shared instance per struct type. The same schema struct tag covers naming, exclusion, required fields, and defaults, and the dotted/indexed path convention for nested structs and slices is a well-documented, deliberate solution to a real gap: the standard library has no built-in way to decode form values into typed structs.
Used by 4 apps in this directory
Hatchet
AI Development · Developer Tools · Automation
A Postgres-backed orchestration engine for background tasks, AI agents, and durable workflows that replaces Redis queues and multi-datastore durable execution platforms with a single self-hostable service.
Mattermost
Team Chat · Collaboration · Devops
Open core, self-hosted team collaboration with chat, AI agents, voice calling, and deep DevOps integrations — all under your control.
Wakapi
Developer Tools · Analytics
Self-hosted WakaTime-compatible coding statistics backend that gives developers full control over their coding activity data.
ZITADEL
Authentication
Open-source, API-first identity platform delivering multi-tenancy, Passkeys, OIDC, SAML, and SCIM without vendor lock-in.