zoobzio December 15, 2025 Edit this page

Rocco

Type-safe HTTP framework for Go with automatic OpenAPI generation.

Rocco provides a declarative, type-safe approach to building HTTP APIs. Define your handlers with generic types, and rocco handles request parsing, error responses, and OpenAPI documentation automatically.

Why Rocco?

Building HTTP APIs in Go typically involves repetitive boilerplate: parsing request bodies, validating inputs, mapping errors to status codes, and keeping documentation in sync. Rocco eliminates this friction through a type-driven design.

┌─────────────────────────────────────────────────────────────┐
│                        Your Code                            │
│  ┌─────────────────────────────────────────────────────┐   │
│  │   type Input struct { Name string `validate:"req"` }│   │
│  │   type Output struct { ID string }                  │   │
│  │   func Handle(req) (Output, error) { ... }          │   │
│  └─────────────────────────────────────────────────────┘   │
└──────────────────────────┬──────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│                        Rocco                                │
│  ┌────────────┐  ┌────────────┐  ┌────────────────────┐    │
│  │   Parse    │→ │  Validate  │→ │  Execute Handler   │    │
│  │   JSON     │  │   Input    │  │  + Marshal Output  │    │
│  └────────────┘  └────────────┘  └────────────────────┘    │
│                                                             │
│  ┌────────────────────────────────────────────────────┐    │
│  │           OpenAPI Spec Generation                   │    │
│  │   (schemas, params, errors from your types)        │    │
│  └────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

Design Principles

Type Safety First

Every handler declares its input and output types. The compiler catches mismatches, and the framework uses these types to generate accurate OpenAPI schemas.

// Compile-time type safety
handler := rocco.NewHandler[CreateUserInput, UserOutput](...)

// req.Body is CreateUserInput, not any or interface{}
func(req *rocco.Request[CreateUserInput]) (UserOutput, error) {
    return UserOutput{Name: req.Body.Name}, nil
}

Explicit Over Magic

No hidden configuration files, no reflection-based routing, no implicit middleware. Every behavior is declared in code.

handler.
    WithPathParams("id").           // Explicit path params
    WithQueryParams("page", "limit"). // Explicit query params
    WithErrors(ErrNotFound).        // Explicit error declarations
    WithScopes("users:read")        // Explicit authorization

Documentation as Code

OpenAPI schemas are generated from your types. When you change a struct field, the documentation updates automatically. No manual syncing required.

Errors as Values

Error handling uses sentinel errors with structured responses. Declare which errors a handler may return, and rocco enforces this at runtime while generating accurate error schemas.

Core Capabilities

Typed Handlers

Generic handlers with compile-time type checking for request bodies and responses.

Type-Based Validation

Types that implement the Validatable interface are automatically validated. Use any validation library (like go-playground/validator) or write custom logic. The validate struct tag is parsed for OpenAPI schema generation.

OpenAPI Generation

Full OpenAPI 3.1.0 specs generated from your code, including request/response schemas, parameters, and error responses.

Identity & Authorization

Built-in support for identity extraction, scope-based authorization, role-based access control, and usage limits.

Structured Errors

Typed error responses with codes, messages, and optional details. Custom errors with typed detail schemas for comprehensive API contracts.

Observability

Event emission via capitan for request lifecycle, handler execution, and error tracking.

Stdlib Router

Built on Go 1.22+ stdlib http.ServeMux with native path parameter support. Zero external router dependencies.

Quick Example

package main

import "github.com/zoobz-io/rocco"

type CreateUserInput struct {
    Name  string `json:"name" validate:"required,min=2"`
    Email string `json:"email" validate:"required,email"`
}

type UserOutput struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

func main() {
    engine := rocco.NewEngine()

    handler := rocco.NewHandler[CreateUserInput, UserOutput](
        "create-user",
        "POST",
        "/users",
        func(req *rocco.Request[CreateUserInput]) (UserOutput, error) {
            return UserOutput{
                ID:    "usr_123",
                Name:  req.Body.Name,
                Email: req.Body.Email,
            }, nil
        },
    ).WithSuccessStatus(201)

    engine.WithHandlers(handler)
    engine.Start(rocco.HostAll, 8080)
}

Next Steps

See Also