REST framework + OpenAPI SDK generation for the Lethean Go ecosystem
- Go 100%
Introduces pkg/provider/ with Provider, Streamable, Describable, and Renderable interfaces that extend api.RouteGroup. The Registry type collects providers and mounts them on an api.Engine via Register(), inheriting middleware, CORS, Swagger, and OpenAPI for free. Includes capability query methods and ProviderInfo serialisation. Phase 3 ProxyProvider stub for polyglot providers. Co-Authored-By: Virgil <virgil@lethean.io> |
||
|---|---|---|
| .core | ||
| .forgejo/workflows | ||
| .idea | ||
| cmd/api | ||
| docs | ||
| pkg/provider | ||
| .editorconfig | ||
| .golangci.yml | ||
| api.go | ||
| api_test.go | ||
| authentik.go | ||
| authentik_integration_test.go | ||
| authentik_test.go | ||
| authz_test.go | ||
| bridge.go | ||
| bridge_test.go | ||
| brotli.go | ||
| brotli_test.go | ||
| cache.go | ||
| cache_test.go | ||
| CLAUDE.md | ||
| codegen.go | ||
| codegen_test.go | ||
| CONTRIBUTING.md | ||
| export.go | ||
| export_test.go | ||
| expvar_test.go | ||
| go.mod | ||
| go.sum | ||
| graphql.go | ||
| graphql_test.go | ||
| group.go | ||
| group_test.go | ||
| gzip_test.go | ||
| httpsign_test.go | ||
| i18n.go | ||
| i18n_test.go | ||
| LICENCE | ||
| location_test.go | ||
| middleware.go | ||
| middleware_test.go | ||
| modernization_test.go | ||
| norace_test.go | ||
| openapi.go | ||
| openapi_test.go | ||
| options.go | ||
| pprof_test.go | ||
| race_test.go | ||
| README.md | ||
| response.go | ||
| response_test.go | ||
| secure_test.go | ||
| sessions_test.go | ||
| slog_test.go | ||
| sse.go | ||
| sse_test.go | ||
| static_test.go | ||
| swagger.go | ||
| swagger_test.go | ||
| timeout_test.go | ||
| tracing.go | ||
| tracing_test.go | ||
| websocket.go | ||
| websocket_test.go | ||
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
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
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
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:
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():
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()andRequireGroup()guards - WebSocket —
WithWSHandler()mounts anyhttp.Handlerat/ws - Swagger UI —
WithSwagger()serves interactive API docs at/swagger/ - Health check — Built-in
GET /healthendpoint
Licence
EUPL-1.2