Getting Started

Introduction

What ezz is, what it does for you, and when it is the right choice.

ezz is a Go framework for JSON APIs. You write a function that takes a typed request struct and returns a typed response, register it on a route, and ezz takes care of the parts that are the same in every service: reading values out of the request, validating them, rejecting unauthenticated callers, shaping errors, and describing the endpoint in an OpenAPI document.

It is a thin layer, not a platform. Routing is Go's own net/http.ServeMux. Middleware is func(http.Handler) http.Handler. An *ezz.App is an http.Handler, and every handler you write is one too, so you can mix ezz code with plain net/http code in the same binary.

What ezz does for you

  • Binds requests. Struct tags map path segments, query parameters, headers, form fields, and the JSON body onto your request type.
  • Validates input. A validate tag rejects bad input with a 400 before your function runs.
  • Authenticates and authorizes. Register an auth provider and routes require a valid token unless you mark them public. Role and permission rules live on the route.
  • Resolves authorization from your data. Roles and permissions come from a resolver you implement against your own tables, not from a token claim.
  • Documents itself. The OpenAPI 3 spec is generated from your handler types and served next to a Scalar UI.
  • Fronts GoTrue. If you use GoTrue or Supabase Auth, ezz can proxy it so the auth server never faces the internet.

What a handler looks like

main.go
type CreateUserRequest struct {
    Name  string `json:"name" validate:"required,min=2,max=100"`
    Email string `json:"email" validate:"required,email"`
}

app.POST("/users", ezz.H(func(ctx *ezz.Context, req CreateUserRequest) (*User, error) {
    if store.EmailTaken(req.Email) {
        return nil, ezz.Conflict("email already registered")
    }
    return store.Create(req.Name, req.Email), nil
}))

By the time your function runs, the body has been decoded, Name and Email have been checked, and the caller has been authenticated. Returning an error writes a JSON error body with a matching status code. Returning a value writes it as JSON with 200.

When to reach for it

ezz fits services that speak JSON over HTTP and want types and documentation to stay in sync: internal APIs, mobile and SPA backends, and anything sitting in front of GoTrue. It is a good fit when you like the standard library and want a little structure on top of it.

It is not a batteries-included web framework. There is no ORM, no template engine, no asset pipeline, and no background job runner. If you need server-rendered HTML or websockets as a first-class concern, use ezz for the JSON parts and plain net/http for the rest.

Requirements

  • Go 1.22 or newer, for method-aware ServeMux patterns and Request.PathValue. The module itself is built with the Go 1.25 toolchain.
  • No third-party dependencies for the core packages (ezz, ezz/binding, ezz/middleware, ezz/openapi, ezz/auth). The optional ezz/auth/ratelimit package brings in a Redis client.

Where to go next

Installation

Add the module and check your setup works.

Quick start

A complete authenticated API with generated docs.

Handlers

How typed handlers, responses, and errors work.

Auth

Providers, route rules, roles, and permissions.
Copyright © 2026