Installation
Check your Go version
ezz uses method-aware routing patterns (GET /users/{id}) and Request.PathValue, both of which arrived in Go 1.22.
go version
Configure private module access
sulv-io/ezz is a private repository. The public module proxy and checksum database cannot read it, so go get fails with a 410 Gone or 404 Not Found until you tell Go to bypass both and tell Git how to authenticate. This is a one-time setup per machine.
Mark the module as private
go env -w GOPRIVATE='github.com/sulv-io/*'
GOPRIVATE is a convenience switch that sets GONOPROXY and GONOSUMDB to the same pattern. Go then fetches anything under github.com/sulv-io/ straight from the source and skips the sum.golang.org lookup that would otherwise fail on a repository it cannot see.
Let Git authenticate
Go always requests modules over HTTPS. Rewrite that to SSH so your existing key does the work:
git config --global url."git@github.com:sulv-io/".insteadOf "https://github.com/sulv-io/"
If you use a personal access token instead of a key, rewrite to an authenticated HTTPS URL. The token needs repo scope:
git config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/sulv-io/".insteadOf "https://github.com/sulv-io/"
Verify
go env GOPRIVATE
git ls-remote git@github.com:sulv-io/ezz.git HEAD
The first prints github.com/sulv-io/*. The second prints a commit hash. If it asks for a password or reports Repository not found, the credential is the problem, not Go.
~/.gitconfig. Prefer SSH on workstations, and prefer a short-lived token injected as an environment variable in CI.Add the module
go get github.com/sulv-io/ezz
The core packages import only the standard library:
| Import path | What it holds |
|---|---|
github.com/sulv-io/ezz | App, routing, handlers, context, errors, middleware |
github.com/sulv-io/ezz/binding | Request binding and validation |
github.com/sulv-io/ezz/middleware | Gzip, rate limiting |
github.com/sulv-io/ezz/openapi | Spec generation and the Scalar UI |
github.com/sulv-io/ezz/auth | JWT providers, auth rules, resolvers, GoTrue |
One optional package pulls in a dependency. Add it only if you want Redis-backed rate limiting on the GoTrue proxy:
go get github.com/sulv-io/ezz/auth/ratelimit
Pick a version
Use v1.1.0 or later.
go get github.com/sulv-io/ezz@v1.1.0
v1.0.0 does not work with the import paths on this page. That tag predates the rewrite that moved the framework to the module root, so at v1.0.0 there is no package at github.com/sulv-io/ezz and the core packages live under core/ instead. go get appears to succeed and the import then fails with no required module provides package. If you see that error, check which version you resolved with go list -m github.com/sulv-io/ezz.Set up CI
CI runners have neither your go env settings nor your ~/.gitconfig, so the same two pieces of configuration have to be applied in the workflow. With GitHub Actions:
- name: Configure private module access
env:
GITHUB_TOKEN: ${{ secrets.EZZ_READ_TOKEN }}
run: |
go env -w GOPRIVATE='github.com/sulv-io/*'
git config --global \
url."https://x-access-token:${GITHUB_TOKEN}@github.com/sulv-io/".insteadOf \
"https://github.com/sulv-io/"
The default GITHUB_TOKEN is scoped to the repository running the workflow and cannot read a different private repository. Use a fine-grained PAT or a GitHub App token with read access to sulv-io/ezz, stored as a secret.
git@github.com: rewrite from the previous section instead and skip the token entirely.Serve a request
Create a file and run it:
package main
import (
"log"
"github.com/sulv-io/ezz"
)
type PingResponse struct {
Message string `json:"message"`
}
func main() {
app := ezz.New()
app.GET("/ping", ezz.HFunc(func(ctx *ezz.Context) (*PingResponse, error) {
return &PingResponse{Message: "pong"}, nil
}))
log.Fatal(app.Listen(":8080"))
}
go run main.go
curl -i localhost:8080/ping
You should see a 200 with {"message":"pong"}, an X-Request-ID header added by the default middleware, and a request line in the server log.
app.Auth(...), routes require a valid token unless you mark them .Public(). See Auth overview.Next steps
- Quick start builds a real API with auth, groups, and generated docs.
- Routing covers patterns, groups, and route metadata.