93 lines
2.8 KiB
Markdown
93 lines
2.8 KiB
Markdown
[](https://pkg.go.dev/forge.lthn.ai/core/go-api)
|
|
[](LICENSE.md)
|
|
[](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
|