# REST API Handlers Architecture in AgentsView: A Modular Huma-Based Design

> Explore the AgentsView REST API handlers architecture. Learn about its three-layer design using the Huma router for clean separation of concerns, routing, and business logic.

- Repository: [Kenn Software/agentsview](https://github.com/kenn-io/agentsview)
- Tags: architecture
- Published: 2026-06-12

---

**AgentsView implements its REST API handlers using a three-layer architecture built on the Huma router library, separating routing configuration, thin endpoint handlers, and delegated business logic into distinct concerns.**

The AgentsView codebase (available at kenn-io/agentsview) organizes its HTTP interface through a clean, modular REST API handlers architecture that leverages the Huma framework for type-safe routing. This design splits responsibilities across router configuration, handler implementation, and data access layers, making the API extensible and testable.

## Three-Layer Architecture of the REST API Handlers

The REST API handlers architecture in AgentsView follows a strict separation of concerns across three distinct layers.

### Router and Route Groups

The top-level routing logic resides in [`internal/server/huma_route_groups.go`](https://github.com/kenn-io/agentsview/blob/main/internal/server/huma_route_groups.go). This file defines the main Huma router instance, registers sub-routers for each logical domain (sessions, search, settings, etc.), and applies shared middleware including logging, authentication, request ID injection, and timeout handling. The router groups aggregate related endpoints under common path prefixes such as `/api/v1/sessions`.

### Endpoint Handler Functions

Individual handler files follow the naming convention `huma_routes_[domain].go` (e.g., [`huma_routes_sessions.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_sessions.go), [`huma_routes_search.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_search.go), [`huma_routes_pins.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_pins.go)). Each file contains tiny, single-purpose handler functions that receive a `*huma.Context` parameter. These handlers remain deliberately thin: they validate input through typed request structs, delegate data operations to the database layer, translate models into API DTOs, and write JSON responses or SSE events.

### Business Logic and Data Access

Heavy computational work lives outside the handlers in dedicated packages under `internal/db`, `internal/postgres`, `internal/parser`, and `internal/sync`. Handlers import these packages to execute SQL queries, FTS5 search operations, analytics calculations, and file import pipelines. This delegation ensures that `huma_routes_*.go` files contain only HTTP-specific concerns while complex business rules remain testable in isolation.

## Request Flow Through the Handler Pipeline

When a client sends an HTTP request, it traverses a standardized pipeline before returning a response:

1. **Incoming request** arrives via `net/http` and enters the Huma router created in [`internal/server/server.go`](https://github.com/kenn-io/agentsview/blob/main/internal/server/server.go).
2. **Path matching** occurs as the router compares the request path and HTTP verb against registered route groups (e.g., `/api/v1/sessions/:id`).
3. **Middleware chain** executes from [`internal/server/middleware.go`](https://github.com/kenn-io/agentsview/blob/main/internal/server/middleware.go), handling authentication, request ID injection, and timeout management.
4. **Handler invocation** passes a typed request struct (e.g., `SessionDetailRequest`) and the response writer (`*huma.Context`) to the specific endpoint function.
5. **Service delegation** occurs as the handler calls the appropriate database or service layer (e.g., `h.db.GetSessionByID`).
6. **Response marshaling** converts results into a response struct (e.g., `SessionDetailResponse`) and writes JSON to the client.
7. **Streaming handling** for SSE endpoints registers the connection with [`broadcaster.go`](https://github.com/kenn-io/agentsview/blob/main/broadcaster.go) to push real-time events to subscribed clients.

## Handler Implementation Pattern

All REST API handlers follow an identical structural pattern. A typical implementation in [`huma_routes_sessions.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_sessions.go) looks like this:

```go
func (h *handler) GetSessionDetail(ctx *huma.Context) error {
    // 1️⃣ Validate & decode request parameters (already done by Huma)
    req := ctx.Request.(*SessionDetailRequest)

    // 2️⃣ Call the DB layer
    sess, err := h.db.GetSessionByID(ctx, req.ID)
    if err != nil {
        return ctx.Error(http.StatusNotFound, "session not found", err)
    }

    // 3️⃣ Build response DTO
    resp := SessionDetailResponse{
        ID:      sess.ID,
        Title:   sess.Title,
        Created: sess.Created,
        // …
    }

    // 4️⃣ Write JSON
    return ctx.JSON(http.StatusOK, resp)
}

```

Because Huma generates request and response structs from the OpenAPI specification defined in [`openapi.go`](https://github.com/kenn-io/agentsview/blob/main/openapi.go), the API contract remains synchronized with the implementation automatically.

## Endpoint Categories and Route Organization

The REST API handlers are organized into logical groups, each residing in its own `huma_routes_*.go` file:

- **Sessions** ([`huma_routes_sessions.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_sessions.go)): `GET /api/v1/sessions`, `GET /api/v1/sessions/:id`, delete, and export operations.
- **Search** ([`huma_routes_search.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_search.go)): `GET /api/v1/search?q=…` for full-text search across session messages using FTS5.
- **Pins** ([`huma_routes_pins.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_pins.go)): `POST /api/v1/pins` and `DELETE /api/v1/pins/:id` for managing user-defined pinned snippets.
- **Settings** ([`huma_routes_settings.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_settings.go)): `GET` and `PATCH /api/v1/settings` for user-level UI preferences.
- **Analytics** ([`huma_routes_analytics.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_analytics.go)): `GET /api/v1/analytics/summary` for aggregated usage statistics.
- **Import** ([`huma_routes_import.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_import.go)): `POST /api/v1/import` for accepting session file archives and triggering the parser pipeline.
- **Events** ([`huma_routes_events.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_events.go) via [`events.go`](https://github.com/kenn-io/agentsview/blob/main/events.go) and [`broadcaster.go`](https://github.com/kenn-io/agentsview/blob/main/broadcaster.go)): `GET /api/v1/events` for Server-Sent Events (SSE) real-time updates.
- **Health** (in [`server.go`](https://github.com/kenn-io/agentsview/blob/main/server.go) or dedicated routes): `GET /api/v1/health` and `GET /api/v1/metadata` for liveness probes.

## Key Source Files in the Architecture

Understanding the REST API handlers architecture requires familiarity with these specific files:

- **[`internal/server/server.go`](https://github.com/kenn-io/agentsview/blob/main/internal/server/server.go)**: Creates the Huma router, wires middleware, and starts the HTTP server.
- **[`internal/server/huma_route_groups.go`](https://github.com/kenn-io/agentsview/blob/main/internal/server/huma_route_groups.go)**: Configures top-level route groups and sub-router registration.
- **[`internal/server/middleware.go`](https://github.com/kenn-io/agentsview/blob/main/internal/server/middleware.go)**: Implements common middleware for logging, authentication, request IDs, and timeouts.
- **`huma_routes_*.go`**: Individual handler files for each domain (sessions, search, pins, settings, analytics, import).
- **[`broadcaster.go`](https://github.com/kenn-io/agentsview/blob/main/broadcaster.go)**: Central hub managing SSE event distribution to connected clients.
- **[`openapi.go`](https://github.com/kenn-io/agentsview/blob/main/openapi.go)**: OpenAPI specification used by Huma to generate typed request/response structs.
- **`internal/db/*.go`**, **`internal/postgres/*.go`**, **`internal/parser/*.go`**, **`internal/sync/*.go`**: Business logic and data access layers called by handlers.

## Summary

- **AgentsView uses a three-layer architecture** for its REST API handlers: router configuration, thin HTTP handlers, and delegated business logic.
- **The Huma framework** provides type-safe routing and automatic request/response validation via OpenAPI specifications in [`openapi.go`](https://github.com/kenn-io/agentsview/blob/main/openapi.go).
- **Handlers remain deliberately thin**, delegating complex operations to packages like `internal/db` and `internal/parser` while focusing on HTTP concerns.
- **Middleware** (logging, auth, timeouts) is applied at the router group level in [`huma_route_groups.go`](https://github.com/kenn-io/agentsview/blob/main/huma_route_groups.go).
- **Real-time features** use Server-Sent Events managed by [`broadcaster.go`](https://github.com/kenn-io/agentsview/blob/main/broadcaster.go) alongside standard JSON endpoints.

## Frequently Asked Questions

### Why does AgentsView use the Huma router instead of the standard library?

AgentsView adopts the Huma router because it generates type-safe request and response structs directly from the OpenAPI specification defined in [`openapi.go`](https://github.com/kenn-io/agentsview/blob/main/openapi.go). This eliminates manual JSON marshaling errors, ensures the API documentation always matches the implementation, and provides built-in validation before handlers execute. According to the source code, this approach keeps handler functions in files like [`huma_routes_sessions.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_sessions.go) focused on business logic rather than boilerplate parsing.

### How does the REST API handler architecture support real-time updates?

The architecture supports real-time updates through Server-Sent Events (SSE) handled in [`huma_routes_events.go`](https://github.com/kenn-io/agentsview/blob/main/huma_routes_events.go) and managed by [`broadcaster.go`](https://github.com/kenn-io/agentsview/blob/main/broadcaster.go). When a client connects to `GET /api/v1/events`, the handler registers the connection with the broadcaster, which maintains a registry of active client streams. When data changes occur elsewhere in the system, the broadcaster pushes events to all subscribed connections while the main handler logic remains stateless and non-blocking.

### Where is authentication middleware applied in the request flow?

Authentication middleware is applied at the router group level in [`internal/server/huma_route_groups.go`](https://github.com/kenn-io/agentsview/blob/main/internal/server/huma_route_groups.go). The middleware chain defined in [`internal/server/middleware.go`](https://github.com/kenn-io/agentsview/blob/main/internal/server/middleware.go) runs after the router matches a request path but before the specific handler function executes. This ensures that authentication, logging, and request ID injection occur consistently across all endpoints within a route group without requiring repetitive code in individual handlers.

### How are request and response structs validated in the API handlers?

Validation occurs automatically through Huma's OpenAPI integration. The [`openapi.go`](https://github.com/kenn-io/agentsview/blob/main/openapi.go) file defines the API contract, which Huma uses to generate typed structs like `SessionDetailRequest` and `SessionDetailResponse`. When a request arrives, Huma validates the input against the specification before the handler function receives the context. If validation fails, Huma returns an appropriate error response before execution reaches the business logic in `huma_routes_*.go` files.