api

package module
v0.1.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 17, 2026 License: EUPL-1.2 Imports: 53 Imported by: 0

Documentation

Overview

Package api provides a Gin-based REST framework with OpenAPI generation. Subsystems implement RouteGroup to register their own endpoints.

Index

Constants

View Source
const (
	// BrotliBestSpeed is the lowest (fastest) Brotli compression level.
	BrotliBestSpeed = brotli.BestSpeed

	// BrotliBestCompression is the highest (smallest output) Brotli level.
	BrotliBestCompression = brotli.BestCompression

	// BrotliDefaultCompression is the default Brotli compression level.
	BrotliDefaultCompression = brotli.DefaultCompression
)

Variables

This section is empty.

Functions

func ExportSpec

func ExportSpec(w io.Writer, format string, builder *SpecBuilder, groups []RouteGroup) error

ExportSpec generates the OpenAPI spec and writes it to w. Format must be "json" or "yaml".

func ExportSpecToFile

func ExportSpecToFile(path, format string, builder *SpecBuilder, groups []RouteGroup) error

ExportSpecToFile writes the spec to the given path. The parent directory is created if it does not exist.

func GetLocale

func GetLocale(c *gin.Context) string

GetLocale returns the detected locale for the current request. Returns "en" if the i18n middleware was not applied.

func GetMessage

func GetMessage(c *gin.Context, key string) (string, bool)

GetMessage looks up a localised message by key for the current request. Returns the message string and true if found, or empty string and false if the key does not exist or the i18n middleware was not applied.

func NewTracerProvider

func NewTracerProvider(exporter sdktrace.SpanExporter) *sdktrace.TracerProvider

NewTracerProvider creates a TracerProvider configured with the given SpanExporter and returns it. The caller is responsible for calling Shutdown on the returned provider when the application exits.

This is a convenience helper for tests and simple deployments. Production setups should build their own TracerProvider with batching, resource attributes, and appropriate exporters.

func RequireAuth

func RequireAuth() gin.HandlerFunc

RequireAuth is Gin middleware that rejects unauthenticated requests. It checks for a user set by the Authentik middleware and returns 401 when none is present.

func RequireGroup

func RequireGroup(group string) gin.HandlerFunc

RequireGroup is Gin middleware that rejects requests from users who do not belong to the specified group. Returns 401 when no user is present and 403 when the user lacks the required group membership.

func SupportedLanguages

func SupportedLanguages() []string

SupportedLanguages returns the list of supported SDK target languages in sorted order for deterministic output.

func SupportedLanguagesIter

func SupportedLanguagesIter() iter.Seq[string]

SupportedLanguagesIter returns an iterator over supported SDK target languages in sorted order.

Types

type AuthentikConfig

type AuthentikConfig struct {
	// Issuer is the OIDC issuer URL (e.g. https://auth.example.com/application/o/my-app/).
	Issuer string

	// ClientID is the OAuth2 client identifier.
	ClientID string

	// TrustedProxy enables reading X-authentik-* headers set by a reverse proxy.
	// When false, headers are ignored to prevent spoofing from untrusted sources.
	TrustedProxy bool

	// PublicPaths lists additional paths that do not require authentication.
	// /health and /swagger are always public.
	PublicPaths []string
}

AuthentikConfig holds settings for the Authentik forward-auth integration.

type AuthentikUser

type AuthentikUser struct {
	Username     string   `json:"username"`
	Email        string   `json:"email"`
	Name         string   `json:"name"`
	UID          string   `json:"uid"`
	Groups       []string `json:"groups,omitempty"`
	Entitlements []string `json:"entitlements,omitempty"`
	JWT          string   `json:"-"`
}

AuthentikUser represents an authenticated user extracted from Authentik forward-auth headers or a validated JWT.

func GetUser

func GetUser(c *gin.Context) *AuthentikUser

GetUser retrieves the AuthentikUser from the Gin context. Returns nil when no user has been set (unauthenticated request or middleware not active).

func (*AuthentikUser) HasGroup

func (u *AuthentikUser) HasGroup(group string) bool

HasGroup reports whether the user belongs to the named group.

type DescribableGroup

type DescribableGroup interface {
	RouteGroup
	// Describe returns endpoint descriptions for OpenAPI generation.
	Describe() []RouteDescription
}

DescribableGroup extends RouteGroup with OpenAPI metadata. RouteGroups that implement this will have their endpoints included in the generated OpenAPI specification.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine is the central API server managing route groups and middleware.

func New

func New(opts ...Option) (*Engine, error)

New creates an Engine with the given options. The default listen address is ":8080".

func (*Engine) Addr

func (e *Engine) Addr() string

Addr returns the configured listen address.

func (*Engine) Channels

func (e *Engine) Channels() []string

Channels returns all WebSocket channel names from registered StreamGroups. Groups that do not implement StreamGroup are silently skipped.

func (*Engine) ChannelsIter

func (e *Engine) ChannelsIter() iter.Seq[string]

ChannelsIter returns an iterator over WebSocket channel names from registered StreamGroups.

func (*Engine) Groups

func (e *Engine) Groups() []RouteGroup

Groups returns all registered route groups.

func (*Engine) GroupsIter

func (e *Engine) GroupsIter() iter.Seq[RouteGroup]

GroupsIter returns an iterator over all registered route groups.

func (*Engine) Handler

func (e *Engine) Handler() http.Handler

Handler builds the Gin engine and returns it as an http.Handler. Each call produces a fresh handler reflecting the current set of groups.

func (*Engine) Register

func (e *Engine) Register(group RouteGroup)

Register adds a route group to the engine.

func (*Engine) Serve

func (e *Engine) Serve(ctx context.Context) error

Serve starts the HTTP server and blocks until the context is cancelled, then performs a graceful shutdown allowing in-flight requests to complete.

type Error

type Error struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	Details any    `json:"details,omitempty"`
}

Error describes a failed API request.

type GraphQLOption

type GraphQLOption func(*graphqlConfig)

GraphQLOption configures a GraphQL endpoint.

func WithGraphQLPath

func WithGraphQLPath(path string) GraphQLOption

WithGraphQLPath sets a custom URL path for the GraphQL endpoint. The default path is "/graphql".

func WithPlayground

func WithPlayground() GraphQLOption

WithPlayground enables the GraphQL Playground UI at {path}/playground.

type I18nConfig

type I18nConfig struct {
	// DefaultLocale is the fallback locale when the Accept-Language header
	// is absent or does not match any supported locale. Defaults to "en".
	DefaultLocale string

	// Supported lists the locale tags the application supports.
	// Each entry should be a BCP 47 language tag (e.g. "en", "fr", "de").
	// If empty, only the default locale is supported.
	Supported []string

	// Messages maps locale tags to key-value message pairs.
	// For example: {"en": {"greeting": "Hello"}, "fr": {"greeting": "Bonjour"}}
	// This is optional — handlers can use GetLocale() alone for custom logic.
	Messages map[string]map[string]string
}

I18nConfig configures the internationalisation middleware.

type Meta

type Meta struct {
	RequestID string `json:"request_id,omitempty"`
	Duration  string `json:"duration,omitempty"`
	Page      int    `json:"page,omitempty"`
	PerPage   int    `json:"per_page,omitempty"`
	Total     int    `json:"total,omitempty"`
}

Meta carries pagination and request metadata.

type Option

type Option func(*Engine)

Option configures an Engine during construction.

func WithAddr

func WithAddr(addr string) Option

WithAddr sets the listen address for the server.

func WithAuthentik

func WithAuthentik(cfg AuthentikConfig) Option

WithAuthentik adds Authentik forward-auth middleware that extracts user identity from X-authentik-* headers set by a trusted reverse proxy. The middleware is permissive: unauthenticated requests are allowed through.

func WithAuthz

func WithAuthz(enforcer *casbin.Enforcer) Option

WithAuthz adds Casbin policy-based authorisation middleware via gin-contrib/authz. The caller provides a pre-configured Casbin enforcer holding the desired model and policy rules. The middleware extracts the subject from HTTP Basic Authentication, evaluates it against the request method and path, and returns 403 Forbidden when the policy denies access.

func WithBearerAuth

func WithBearerAuth(token string) Option

WithBearerAuth adds bearer token authentication middleware. Requests to /health and paths starting with /swagger are exempt.

func WithBrotli

func WithBrotli(level ...int) Option

WithBrotli adds Brotli response compression middleware using andybalholm/brotli. An optional compression level may be supplied (e.g. BrotliBestSpeed, BrotliBestCompression). If omitted, BrotliDefaultCompression is used.

func WithCORS

func WithCORS(allowOrigins ...string) Option

WithCORS configures Cross-Origin Resource Sharing via gin-contrib/cors. Pass "*" to allow all origins, or supply specific origin URLs. Standard methods (GET, POST, PUT, PATCH, DELETE, OPTIONS) and common headers (Authorization, Content-Type, X-Request-ID) are permitted.

func WithCache

func WithCache(ttl time.Duration) Option

WithCache adds in-memory response caching middleware for GET requests. Successful (2xx) GET responses are cached for the given TTL and served with an X-Cache: HIT header on subsequent requests. Non-GET methods and error responses pass through uncached.

func WithExpvar

func WithExpvar() Option

WithExpvar enables the Go runtime metrics endpoint at /debug/vars. The endpoint serves JSON containing memstats, cmdline, and any custom expvar variables registered by the application. Powered by gin-contrib/expvar wrapping Go's standard expvar.Handler().

WARNING: expvar exposes runtime internals (memory allocation, goroutine counts, command-line arguments) and should only be enabled in development or behind authentication in production.

func WithGraphQL

func WithGraphQL(schema graphql.ExecutableSchema, opts ...GraphQLOption) Option

WithGraphQL mounts a GraphQL endpoint serving the given gqlgen ExecutableSchema. By default the endpoint is mounted at "/graphql". Use GraphQLOption helpers to enable the playground UI or customise the path:

api.New(
    api.WithGraphQL(schema, api.WithPlayground(), api.WithGraphQLPath("/gql")),
)

func WithGzip

func WithGzip(level ...int) Option

WithGzip adds gzip response compression middleware via gin-contrib/gzip. An optional compression level may be supplied (e.g. gzip.BestSpeed, gzip.BestCompression). If omitted, gzip.DefaultCompression is used.

func WithHTTPSign

func WithHTTPSign(secrets httpsign.Secrets, opts ...httpsign.Option) Option

WithHTTPSign adds HTTP signature verification middleware via gin-contrib/httpsign. Incoming requests must carry a valid cryptographic signature in the Authorization or Signature header as defined by the HTTP Signatures specification (draft-cavage-http-signatures).

The caller provides a key store mapping key IDs to secrets (each pairing a shared key with a signing algorithm). Optional httpsign.Option values may configure required headers or custom validators; sensible defaults apply when omitted (date, digest, and request-target headers are required; date and digest validators are enabled).

Requests with a missing, malformed, or invalid signature are rejected with 401 Unauthorised or 400 Bad Request.

func WithI18n

func WithI18n(cfg ...I18nConfig) Option

WithI18n adds Accept-Language header parsing and locale detection middleware. The middleware uses golang.org/x/text/language for RFC 5646 language matching with quality weighting support. The detected locale is stored in the Gin context and can be retrieved by handlers via GetLocale().

If messages are configured, handlers can look up localised strings via GetMessage(). This is a lightweight bridge — the go-i18n grammar engine can replace the message map later.

func WithLocation

func WithLocation() Option

WithLocation adds reverse proxy header detection middleware via gin-contrib/location. It inspects X-Forwarded-Proto and X-Forwarded-Host headers to determine the original scheme and host when the server runs behind a TLS-terminating reverse proxy such as Traefik.

After this middleware runs, handlers can call location.Get(c) to retrieve a *url.URL with the detected scheme, host, and base path.

func WithMiddleware

func WithMiddleware(mw ...gin.HandlerFunc) Option

WithMiddleware appends arbitrary Gin middleware to the engine.

func WithPprof

func WithPprof() Option

WithPprof enables Go runtime profiling endpoints at /debug/pprof/. The standard pprof handlers (index, cmdline, profile, symbol, trace, allocs, block, goroutine, heap, mutex, threadcreate) are registered via gin-contrib/pprof.

WARNING: pprof exposes sensitive runtime data and should only be enabled in development or behind authentication in production.

func WithRequestID

func WithRequestID() Option

WithRequestID adds middleware that assigns an X-Request-ID to every response. Client-provided IDs are preserved; otherwise a random hex ID is generated.

func WithSSE

func WithSSE(broker *SSEBroker) Option

WithSSE registers a Server-Sent Events broker at GET /events. Clients connect to the endpoint and receive a streaming text/event-stream response. The broker manages client connections and broadcasts events published via its Publish method.

func WithSecure

func WithSecure() Option

WithSecure adds security headers middleware via gin-contrib/secure. Default policy sets HSTS (1 year, includeSubDomains), X-Frame-Options DENY, X-Content-Type-Options nosniff, and Referrer-Policy strict-origin-when-cross-origin. SSL redirect is not enabled so the middleware works behind a reverse proxy that terminates TLS.

func WithSessions

func WithSessions(name string, secret []byte) Option

WithSessions adds server-side session management middleware via gin-contrib/sessions using a cookie-based store. The name parameter sets the session cookie name (e.g. "session") and secret is the key used for cookie signing and encryption.

func WithSlog

func WithSlog(logger *slog.Logger) Option

WithSlog adds structured request logging middleware via gin-contrib/slog. Each request is logged with method, path, status code, latency, and client IP. If logger is nil, slog.Default() is used.

func WithStatic

func WithStatic(urlPrefix, root string) Option

WithStatic serves static files from the given root directory at urlPrefix. Directory listing is disabled; only individual files are served. Internally this uses gin-contrib/static as Gin middleware.

func WithSwagger

func WithSwagger(title, description, version string) Option

WithSwagger enables the Swagger UI at /swagger/. The title, description, and version populate the OpenAPI info block.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout adds per-request timeout middleware via gin-contrib/timeout. If a handler exceeds the given duration, the request is aborted with a 504 Gateway Timeout carrying the standard error envelope:

{"success":false,"error":{"code":"timeout","message":"Request timed out"}}

A zero or negative duration effectively disables the timeout (the handler runs without a deadline) — this is safe and will not panic.

func WithTracing

func WithTracing(serviceName string, opts ...otelgin.Option) Option

WithTracing adds OpenTelemetry distributed tracing middleware via otelgin. Each incoming request produces a span tagged with the HTTP method, route, and status code. Trace context is propagated using W3C traceparent headers.

The serviceName identifies this service in distributed traces. If a TracerProvider has not been configured globally via otel.SetTracerProvider, the middleware uses the global default (which is a no-op until set).

Typical setup in main:

tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
otel.SetTracerProvider(tp)
otel.SetTextMapPropagator(propagation.TraceContext{})

engine, _ := api.New(api.WithTracing("my-service"))

func WithWSHandler

func WithWSHandler(h http.Handler) Option

WithWSHandler registers a WebSocket handler at GET /ws. Typically this wraps a go-ws Hub.Handler().

type Response

type Response[T any] struct {
	Success bool   `json:"success"`
	Data    T      `json:"data,omitempty"`
	Error   *Error `json:"error,omitempty"`
	Meta    *Meta  `json:"meta,omitempty"`
}

Response is the standard envelope for all API responses.

func Fail

func Fail(code, message string) Response[any]

Fail creates an error response with the given code and message.

func FailWithDetails

func FailWithDetails(code, message string, details any) Response[any]

FailWithDetails creates an error response with additional detail payload.

func OK

func OK[T any](data T) Response[T]

OK wraps data in a successful response envelope.

func Paginated

func Paginated[T any](data T, page, perPage, total int) Response[T]

Paginated wraps data in a successful response with pagination metadata.

type RouteDescription

type RouteDescription struct {
	Method      string         // HTTP method: GET, POST, PUT, DELETE, PATCH
	Path        string         // Path relative to BasePath, e.g. "/generate"
	Summary     string         // Short summary
	Description string         // Long description
	Tags        []string       // OpenAPI tags for grouping
	RequestBody map[string]any // JSON Schema for request body (nil for GET)
	Response    map[string]any // JSON Schema for success response data
}

RouteDescription describes a single endpoint for OpenAPI generation.

type RouteGroup

type RouteGroup interface {
	// Name returns a human-readable identifier for the group.
	Name() string

	// BasePath returns the URL prefix for all routes in this group.
	BasePath() string

	// RegisterRoutes mounts handlers onto the provided router group.
	RegisterRoutes(rg *gin.RouterGroup)
}

RouteGroup registers API routes onto a Gin router group. Subsystems implement this interface to declare their endpoints.

type SDKGenerator

type SDKGenerator struct {
	// SpecPath is the path to the OpenAPI spec file (JSON or YAML).
	SpecPath string

	// OutputDir is the base directory for generated SDK output.
	OutputDir string

	// PackageName is the name used for the generated package/module.
	PackageName string
}

SDKGenerator wraps openapi-generator-cli for SDK generation.

func (*SDKGenerator) Available

func (g *SDKGenerator) Available() bool

Available checks if openapi-generator-cli is installed and accessible.

func (*SDKGenerator) Generate

func (g *SDKGenerator) Generate(ctx context.Context, language string) error

Generate creates an SDK for the given language using openapi-generator-cli. The language must be one of the supported languages returned by SupportedLanguages().

type SSEBroker

type SSEBroker struct {
	// contains filtered or unexported fields
}

SSEBroker manages Server-Sent Events connections and broadcasts events to subscribed clients. Clients connect via a GET endpoint and receive a streaming text/event-stream response. Each client may optionally subscribe to a specific channel via the ?channel= query parameter.

func NewSSEBroker

func NewSSEBroker() *SSEBroker

NewSSEBroker creates a ready-to-use SSE broker.

func (*SSEBroker) ClientCount

func (b *SSEBroker) ClientCount() int

ClientCount returns the number of currently connected SSE clients.

func (*SSEBroker) Drain

func (b *SSEBroker) Drain()

Drain closes all connected clients by writing an empty response. Useful for graceful shutdown.

func (*SSEBroker) Handler

func (b *SSEBroker) Handler() gin.HandlerFunc

Handler returns a Gin handler for the SSE endpoint. Clients connect with a GET request and receive events as text/event-stream. An optional ?channel=<name> query parameter subscribes the client to a specific channel.

func (*SSEBroker) Publish

func (b *SSEBroker) Publish(channel, event string, data any)

Publish sends an event to all clients subscribed to the given channel. Clients subscribed to an empty channel (no ?channel= param) receive events on every channel. The data value is JSON-encoded before sending.

type SpecBuilder

type SpecBuilder struct {
	Title       string
	Description string
	Version     string
}

SpecBuilder constructs an OpenAPI 3.1 specification from registered RouteGroups.

func (*SpecBuilder) Build

func (sb *SpecBuilder) Build(groups []RouteGroup) ([]byte, error)

Build generates the complete OpenAPI 3.1 JSON spec. Groups implementing DescribableGroup contribute endpoint documentation. Other groups are listed as tags only.

type StreamGroup

type StreamGroup interface {
	// Channels returns the list of channel names this group streams on.
	Channels() []string
}

StreamGroup optionally declares WebSocket channels a subsystem publishes to.

type ToolBridge

type ToolBridge struct {
	// contains filtered or unexported fields
}

ToolBridge converts tool descriptors into REST endpoints and OpenAPI paths. It implements both RouteGroup and DescribableGroup.

func NewToolBridge

func NewToolBridge(basePath string) *ToolBridge

NewToolBridge creates a bridge that mounts tool endpoints at basePath.

func (*ToolBridge) Add

func (b *ToolBridge) Add(desc ToolDescriptor, handler gin.HandlerFunc)

Add registers a tool with its HTTP handler.

func (*ToolBridge) BasePath

func (b *ToolBridge) BasePath() string

BasePath returns the URL prefix for all tool endpoints.

func (*ToolBridge) Describe

func (b *ToolBridge) Describe() []RouteDescription

Describe returns OpenAPI route descriptions for all registered tools.

func (*ToolBridge) DescribeIter

func (b *ToolBridge) DescribeIter() iter.Seq[RouteDescription]

DescribeIter returns an iterator over OpenAPI route descriptions for all registered tools.

func (*ToolBridge) Name

func (b *ToolBridge) Name() string

Name returns the bridge identifier.

func (*ToolBridge) RegisterRoutes

func (b *ToolBridge) RegisterRoutes(rg *gin.RouterGroup)

RegisterRoutes mounts POST /{tool_name} for each registered tool.

func (*ToolBridge) Tools

func (b *ToolBridge) Tools() []ToolDescriptor

Tools returns all registered tool descriptors.

func (*ToolBridge) ToolsIter

func (b *ToolBridge) ToolsIter() iter.Seq[ToolDescriptor]

ToolsIter returns an iterator over all registered tool descriptors.

type ToolDescriptor

type ToolDescriptor struct {
	Name         string         // Tool name, e.g. "file_read" (becomes POST path segment)
	Description  string         // Human-readable description
	Group        string         // OpenAPI tag group, e.g. "files"
	InputSchema  map[string]any // JSON Schema for request body
	OutputSchema map[string]any // JSON Schema for response data (optional)
}

ToolDescriptor describes a tool that can be exposed as a REST endpoint.

Directories

Path Synopsis
cmd
api
pkg
provider
Package provider defines the Service Provider Framework interfaces.
Package provider defines the Service Provider Framework interfaces.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL