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.

Agent skill

Teach your coding agent to write EZZ correctly.
Copyright © 2026