[![Go Reference](https://pkg.go.dev/badge/forge.lthn.ai/core/go-api.svg)](https://pkg.go.dev/forge.lthn.ai/core/go-api) [![License: EUPL-1.2](https://img.shields.io/badge/License-EUPL--1.2-blue.svg)](LICENSE.md) [![Go Version](https://img.shields.io/badge/Go-1.26-00ADD8?style=flat&logo=go)](go.mod) # go-api REST framework + OpenAPI SDK generation for the Lethean Go ecosystem. ## Overview go-api provides a Gin-based HTTP engine that subsystems plug into via the `RouteGroup` interface. Each ecosystem package (go-ml, go-rag, go-agentic, etc.) registers its own route group, and go-api handles the HTTP plumbing, middleware, response envelopes, WebSocket integration, and OpenAPI spec generation. ## Quick Start ```go import api "forge.lthn.ai/core/go-api" engine, _ := api.New( api.WithAddr(":8080"), api.WithBearerAuth("my-token"), api.WithCORS("*"), api.WithRequestID(), api.WithSwagger("My API", "Description", "0.1.0"), ) engine.Register(myRoutes) engine.Serve(ctx) ``` ## Implementing a RouteGroup ```go type Routes struct{ service *mypackage.Service } func (r *Routes) Name() string { return "mypackage" } func (r *Routes) BasePath() string { return "/v1/mypackage" } func (r *Routes) RegisterRoutes(rg *gin.RouterGroup) { rg.GET("/items", r.ListItems) rg.POST("/items", r.CreateItem) } func (r *Routes) ListItems(c *gin.Context) { items, _ := r.service.List(c.Request.Context()) c.JSON(200, api.OK(items)) } ``` ## Authentik Integration ```go engine, _ := api.New( api.WithAuthentik(api.AuthentikConfig{ Issuer: "https://auth.lthn.io/application/o/core-api/", ClientID: "core-api", TrustedProxy: true, // Read X-authentik-* headers from Traefik }), ) ``` In handlers, use `GetUser()` to access the authenticated user: ```go func (r *Routes) ListItems(c *gin.Context) { user := api.GetUser(c) // nil if unauthenticated if user != nil { // user.Username, user.Email, user.Groups, user.UID } } ``` For protected routes, use `RequireAuth()` or `RequireGroup()`: ```go func (r *Routes) RegisterRoutes(rg *gin.RouterGroup) { rg.GET("/public", r.PublicEndpoint) rg.GET("/private", api.RequireAuth(), r.PrivateEndpoint) rg.GET("/admin", api.RequireGroup("admins"), r.AdminEndpoint) } ``` ## Features - **Response envelope** — `api.OK()`, `api.Fail()`, `api.Paginated()` for consistent JSON responses - **Middleware** — Bearer auth, CORS, request ID generation, panic recovery - **Authentik** — Forward auth headers + OIDC JWT validation, `RequireAuth()` and `RequireGroup()` guards - **WebSocket** — `WithWSHandler()` mounts any `http.Handler` at `/ws` - **Swagger UI** — `WithSwagger()` serves interactive API docs at `/swagger/` - **Health check** — Built-in `GET /health` endpoint ## Licence EUPL-1.2