openapi

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 23, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package openapi provides automatic OpenAPI 3.0 specification generation for Aegis.

This plugin generates interactive API documentation with:

  • OpenAPI 3.0.3 specification (JSON)
  • Scalar documentation UI (interactive browser interface)
  • Automatic schema generation from Go structs
  • Security scheme definitions (cookie, bearer)
  • Route metadata collection and transformation

Documentation Features:

  • Auto-generates schemas from Go types using reflection
  • Parses validation tags for schema constraints
  • Supports request/response body documentation
  • Security requirements (protected vs public routes)
  • Tag-based organization

Route Structure:

  • GET /openapi.json - OpenAPI specification (JSON)
  • GET /docs - Scalar documentation UI (if enabled)

Usage:

cfg := &openapi.Config{
  Title:          "My API",
  Version:        "1.0.0",
  EnableScalarUI: true,
}
plugin := openapi.New(cfg)
aegis.RegisterPlugin(plugin)

Package openapi provides OpenAPI 3.0 specification types and generation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Components

type Components struct {
	Schemas         map[string]*Schema         `json:"schemas,omitempty"`
	Responses       map[string]*Response       `json:"responses,omitempty"`
	Parameters      map[string]*Parameter      `json:"parameters,omitempty"`
	RequestBodies   map[string]*RequestBody    `json:"requestBodies,omitempty"`
	Headers         map[string]*Header         `json:"headers,omitempty"`
	SecuritySchemes map[string]*SecurityScheme `json:"securitySchemes,omitempty"`
}

Components holds reusable objects for different aspects of the OAS.

type Config

type Config struct {
	// Title for the API documentation
	Title string
	// Version of the API
	Version string
	// Description of the API
	Description string
	// Servers to include in the spec (for multi-environment APIs)
	Servers []Server
	// Contact information for API maintainers
	Contact *Contact
	// License information for the API
	License *License
	// EnableScalarUI enables the Scalar documentation UI at /docs
	EnableScalarUI bool
	// BasePath for the API (e.g., "/auth", "/api/v1")
	BasePath string
}

Config holds OpenAPI plugin configuration.

Example:

cfg := &openapi.Config{
  Title:          "Aegis Authentication API",
  Version:        "1.0.0",
  Description:    "Complete authentication API",
  EnableScalarUI: true,
  BasePath:       "/auth",
  Servers: []openapi.Server{
    {URL: "https://api.example.com", Description: "Production"},
  },
}

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns default OpenAPI configuration.

Default Settings:

  • Title: "Aegis Authentication API"
  • Version: "1.0.0"
  • ScalarUI: Enabled
  • BasePath: "/auth"
  • Server: http://localhost:8080 (development)
  • License: MIT

Returns:

  • *Config: Default configuration ready for customization

type Contact

type Contact struct {
	Name  string `json:"name,omitempty"`
	URL   string `json:"url,omitempty"`
	Email string `json:"email,omitempty"`
}

Contact information for the API.

type Handler

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

Handler handles HTTP requests for OpenAPI documentation.

This handler serves:

  • OpenAPI specification in JSON format
  • Scalar interactive documentation UI

func NewHandler

func NewHandler(plugin *Plugin, router router.Router) *Handler

NewHandler creates a new OpenAPI handler.

Parameters:

  • plugin: Initialized OpenAPI plugin
  • router: Router instance for metadata collection

Returns:

  • *Handler: Handler ready for route registration

func (*Handler) ServeScalarUI

func (h *Handler) ServeScalarUI(w http.ResponseWriter, req *http.Request)

ServeScalarUI serves the Scalar documentation UI.

Scalar Features:

  • Interactive API explorer
  • Request/response examples
  • Try-it-out functionality
  • Authentication testing
  • Schema visualization

Endpoint:

  • Method: GET
  • Path: /docs
  • Auth: Public

Implementation: Uses CDN-hosted Scalar UI (https://cdn.jsdelivr.net/npm/@scalar/api-reference) Loads spec from ./openapi.json endpoint.

Example: Navigate to http://localhost:8080/auth/docs to view interactive documentation.

func (*Handler) ServeSpec

func (h *Handler) ServeSpec(w http.ResponseWriter, _ *http.Request)

ServeSpec serves the OpenAPI specification as JSON.

This endpoint:

  1. Collects latest route metadata from router
  2. Updates OpenAPI spec with new routes
  3. Serializes spec to JSON
  4. Serves with CORS headers for documentation tools

Endpoint:

  • Method: GET
  • Path: /openapi.json
  • Auth: Public

Response:

  • Content-Type: application/json
  • Access-Control-Allow-Origin: * (for Swagger UI, Postman, etc.)

Use Cases:

  • Generate client SDKs
  • Import into Postman/Insomnia
  • Validate API contracts
  • Feed documentation generators
type Header struct {
	Description string  `json:"description,omitempty"`
	Schema      *Schema `json:"schema,omitempty"`
}

Header describes a single header parameter.

type Info

type Info struct {
	Title          string   `json:"title"`
	Description    string   `json:"description,omitempty"`
	TermsOfService string   `json:"termsOfService,omitempty"`
	Contact        *Contact `json:"contact,omitempty"`
	License        *License `json:"license,omitempty"`
	Version        string   `json:"version"`
}

Info provides metadata about the API.

Example:

info := Info{
  Title:       "Aegis API",
  Version:     "1.0.0",
  Description: "Authentication API",
  Contact: &Contact{
    Name:  "API Support",
    Email: "[email protected]",
  },
}

type License

type License struct {
	Name string `json:"name"`
	URL  string `json:"url,omitempty"`
}

License information for the API.

type MediaType

type MediaType struct {
	Schema  *Schema `json:"schema,omitempty"`
	Example any     `json:"example,omitempty"`
}

MediaType provides schema and examples for the media type.

type OAuthFlow

type OAuthFlow struct {
	AuthorizationURL string            `json:"authorizationUrl,omitempty"`
	TokenURL         string            `json:"tokenUrl,omitempty"`
	RefreshURL       string            `json:"refreshUrl,omitempty"`
	Scopes           map[string]string `json:"scopes"`
}

OAuthFlow configuration details.

type OAuthFlows

type OAuthFlows struct {
	Implicit          *OAuthFlow `json:"implicit,omitempty"`
	Password          *OAuthFlow `json:"password,omitempty"`
	ClientCredentials *OAuthFlow `json:"clientCredentials,omitempty"`
	AuthorizationCode *OAuthFlow `json:"authorizationCode,omitempty"`
}

OAuthFlows allows configuration of the supported OAuth Flows.

type Operation

type Operation struct {
	Tags        []string              `json:"tags,omitempty"`
	Summary     string                `json:"summary,omitempty"`
	Description string                `json:"description,omitempty"`
	OperationID string                `json:"operationId,omitempty"`
	Parameters  []Parameter           `json:"parameters,omitempty"`
	RequestBody *RequestBody          `json:"requestBody,omitempty"`
	Responses   map[string]*Response  `json:"responses"`
	Security    []SecurityRequirement `json:"security,omitempty"`
	Deprecated  bool                  `json:"deprecated,omitempty"`
}

Operation describes a single API operation on a path.

This represents an HTTP method (GET, POST, etc.) on a specific path. Each operation defines:

  • Request requirements (parameters, body)
  • Response definitions (status codes, schemas)
  • Security requirements
  • Metadata (tags, summary, description)

Example:

op := &Operation{
  Tags:        []string{"Default"},
  Summary:     "Login",
  Description: "Authenticate user with email and password",
  RequestBody: &RequestBody{...},
  Responses:   map[string]*Response{...},
  Security:    []SecurityRequirement{{"cookieAuth": []string{}}},
}

type Parameter

type Parameter struct {
	Name        string  `json:"name"`
	In          string  `json:"in"` // "query", "header", "path", "cookie"
	Description string  `json:"description,omitempty"`
	Required    bool    `json:"required,omitempty"`
	Schema      *Schema `json:"schema,omitempty"`
	Example     any     `json:"example,omitempty"`
}

Parameter describes a single operation parameter.

type PathItem

type PathItem struct {
	Summary     string     `json:"summary,omitempty"`
	Description string     `json:"description,omitempty"`
	Get         *Operation `json:"get,omitempty"`
	Post        *Operation `json:"post,omitempty"`
	Put         *Operation `json:"put,omitempty"`
	Delete      *Operation `json:"delete,omitempty"`
	Patch       *Operation `json:"patch,omitempty"`
	Options     *Operation `json:"options,omitempty"`
	Head        *Operation `json:"head,omitempty"`
}

PathItem describes operations available on a single path.

type Plugin

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

Plugin provides automatic OpenAPI 3.0 documentation generation.

This plugin integrates with the Aegis routing system to collect route metadata and generate comprehensive API documentation with interactive UI.

Features:

  • Real-time spec generation from route metadata
  • Thread-safe spec updates
  • Scalar UI integration for interactive documentation
  • Multiple security scheme support
  • Schema validation from Go struct tags

func New

func New(cfg *Config) *Plugin

New creates a new OpenAPI plugin with automatic schema generation.

Initialization:

  1. Create base OpenAPI 3.0.3 spec
  2. Configure servers, contact, license
  3. Add security schemes (cookie, bearer)
  4. Add default tags (default, Session)
  5. Add common schemas (Error, Success)

Parameters:

  • cfg: Plugin configuration (uses defaults if nil)

Returns:

  • *Plugin: Configured plugin ready for initialization

Example:

plugin := openapi.New(&openapi.Config{
  Title:   "My API",
  Version: "2.0.0",
})

func (*Plugin) Dependencies

func (p *Plugin) Dependencies() []plugins.Dependency

Dependencies returns plugin dependencies.

func (*Plugin) Description

func (p *Plugin) Description() string

Description returns a human-readable description.

func (*Plugin) GetMigrations

func (p *Plugin) GetMigrations() []plugins.Migration

GetMigrations returns the plugin migrations.

func (*Plugin) GetSchemas

func (p *Plugin) GetSchemas() []plugins.Schema

GetSchemas returns all schemas for all supported dialects

func (*Plugin) GetSpec

func (p *Plugin) GetSpec() *Spec

GetSpec returns a copy of the current OpenAPI spec.

func (*Plugin) Init

func (p *Plugin) Init(_ context.Context, _ plugins.Aegis) error

Init initializes the OpenAPI plugin.

func (*Plugin) MountRoutes

func (p *Plugin) MountRoutes(router router.Router, prefix string)

MountRoutes registers HTTP routes for the plugin.

func (*Plugin) Name

func (p *Plugin) Name() string

Name returns the plugin identifier.

func (*Plugin) ProvidesAuthMethods

func (p *Plugin) ProvidesAuthMethods() []string

ProvidesAuthMethods returns authentication methods provided.

func (*Plugin) RegisterEndpoint

func (p *Plugin) RegisterEndpoint(method, path string, operation *Operation)

RegisterEndpoint adds a custom endpoint to the OpenAPI spec. This allows other plugins and user code to extend the documentation.

func (*Plugin) RegisterRouteMetadata added in v1.2.1

func (p *Plugin) RegisterRouteMetadata(meta core.RouteMetadata)

RegisterRouteMetadata adds a route to the OpenAPI spec from RouteMetadata. This provides a simpler interface for registering user-defined routes that aren't part of the Aegis authentication system.

Example:

openapiPlugin.RegisterRouteMetadata(core.RouteMetadata{
  Method:      "GET",
  Path:        "/api/subscriptions",
  Summary:     "List subscriptions",
  Description: "Get all user subscriptions",
  Tags:        []string{"Subscriptions"},
  Protected:   true,
})

func (*Plugin) RegisterSchema

func (p *Plugin) RegisterSchema(name string, schema *Schema)

RegisterSchema adds a reusable schema component.

func (*Plugin) RegisterSchemaFromType

func (p *Plugin) RegisterSchemaFromType(name string, example any)

RegisterSchemaFromType automatically generates and registers an OpenAPI schema from a Go type. This eliminates the need for manual schema definitions and ensures schemas stay in sync with Go structs.

Example usage:

p.RegisterSchemaFromType("User", core.User{})
p.RegisterSchemaFromType("CreateOrganizationRequest", organizations.CreateOrganizationRequest{})

func (*Plugin) RegisterSecurityScheme

func (p *Plugin) RegisterSecurityScheme(name string, scheme *SecurityScheme)

RegisterSecurityScheme adds a custom security scheme.

func (*Plugin) RegisterTag

func (p *Plugin) RegisterTag(tag Tag)

RegisterTag adds a tag for grouping operations.

func (*Plugin) RequiresTables

func (p *Plugin) RequiresTables() []string

RequiresTables returns required database tables.

func (*Plugin) UpdateSpec

func (p *Plugin) UpdateSpec(metadata []core.RouteMetadata)

UpdateSpec updates the OpenAPI spec with route metadata.

func (*Plugin) Version

func (p *Plugin) Version() string

Version returns the plugin version.

type RequestBody

type RequestBody struct {
	Description string               `json:"description,omitempty"`
	Content     map[string]MediaType `json:"content"`
	Required    bool                 `json:"required,omitempty"`
}

RequestBody describes a single request body.

type Response

type Response struct {
	Description string               `json:"description"`
	Content     map[string]MediaType `json:"content,omitempty"`
	Headers     map[string]*Header   `json:"headers,omitempty"`
}

Response describes a single response from an API operation.

type Schema

type Schema struct {
	Type                 string             `json:"type,omitempty"`
	Format               string             `json:"format,omitempty"`
	Title                string             `json:"title,omitempty"`
	Description          string             `json:"description,omitempty"`
	Properties           map[string]*Schema `json:"properties,omitempty"`
	Required             []string           `json:"required,omitempty"`
	Items                *Schema            `json:"items,omitempty"`
	Enum                 []any              `json:"enum,omitempty"`
	Example              any                `json:"example,omitempty"`
	Ref                  string             `json:"$ref,omitempty"`
	AdditionalProperties any                `json:"additionalProperties,omitempty"`

	// Validation constraints
	MinLength *int     `json:"minLength,omitempty"`
	MaxLength *int     `json:"maxLength,omitempty"`
	Pattern   string   `json:"pattern,omitempty"`
	Minimum   *float64 `json:"minimum,omitempty"`
	Maximum   *float64 `json:"maximum,omitempty"`
	MinItems  *int     `json:"minItems,omitempty"`
	MaxItems  *int     `json:"maxItems,omitempty"`
}

Schema represents a JSON Schema object.

func ArraySchema

func ArraySchema(description string, items *Schema) *Schema

ArraySchema creates an array schema.

func BooleanSchema

func BooleanSchema(description string) *Schema

BooleanSchema creates a boolean schema.

func DateTimeSchema

func DateTimeSchema(description string) *Schema

DateTimeSchema creates a date-time string schema.

func EmailSchema

func EmailSchema(description string) *Schema

EmailSchema creates an email string schema.

func GenerateSchema

func GenerateSchema(v any) *Schema

GenerateSchema creates an OpenAPI schema from a Go struct instance using reflection.

This function analyzes the struct's type information to automatically generate a JSON Schema compatible with OpenAPI 3.0.

Schema Generation:

  1. Inspect struct fields and types
  2. Parse JSON tags for field names
  3. Parse validation tags for constraints
  4. Determine required fields (non-omitempty, validation:"Required")
  5. Generate nested schemas for complex types

Supported Types:

  • Primitives: string, int, bool, float
  • Complex: struct, array, map
  • Special: time.Time (date-time format)

Validation Tags:

  • validation:"Required" -> required field
  • validation:"Length(3,50)" -> minLength/maxLength
  • validation:"Min(1),Max(100)" -> minimum/maximum
  • validation:"Match(^[a-z]+$)" -> pattern

Parameters:

  • v: Go struct instance or pointer to struct

Returns:

  • *Schema: OpenAPI schema with properties and constraints

Example:

type User struct {
  Name  string `json:"name" validation:"Required,Length(1,100)"`
  Email string `json:"email" validation:"Required,Match(^.+@.+$)"`
}
schema := GenerateSchema(User{})

func IntegerSchema

func IntegerSchema(description string) *Schema

IntegerSchema creates an integer schema.

func ObjectSchema

func ObjectSchema(description string, properties map[string]*Schema, required []string) *Schema

ObjectSchema creates an object schema.

func RefSchema

func RefSchema(ref string) *Schema

RefSchema creates a reference to a schema component.

func StringSchema

func StringSchema(description string) *Schema

StringSchema creates a string schema.

func UUIDSchema

func UUIDSchema(description string) *Schema

UUIDSchema creates a UUID string schema.

type SecurityRequirement

type SecurityRequirement map[string][]string

SecurityRequirement lists required security schemes to execute an operation.

type SecurityScheme

type SecurityScheme struct {
	Type             string      `json:"type"` // "apiKey", "http", "oauth2", "openIdConnect"
	Description      string      `json:"description,omitempty"`
	Name             string      `json:"name,omitempty"`             // For apiKey
	In               string      `json:"in,omitempty"`               // For apiKey: "query", "header", "cookie"
	Scheme           string      `json:"scheme,omitempty"`           // For http: "bearer", "basic"
	BearerFormat     string      `json:"bearerFormat,omitempty"`     // For http bearer
	Flows            *OAuthFlows `json:"flows,omitempty"`            // For oauth2
	OpenIDConnectURL string      `json:"openIdConnectUrl,omitempty"` // For openIdConnect
}

SecurityScheme defines a security scheme that can be used by operations.

type Server

type Server struct {
	URL         string                    `json:"url"`
	Description string                    `json:"description,omitempty"`
	Variables   map[string]ServerVariable `json:"variables,omitempty"`
}

Server represents a server URL.

type ServerVariable

type ServerVariable struct {
	Enum        []string `json:"enum,omitempty"`
	Default     string   `json:"Default"`
	Description string   `json:"description,omitempty"`
}

ServerVariable represents a server URL template variable.

type Spec

type Spec struct {
	OpenAPI    string                `json:"openapi"`              // OpenAPI version (3.0.3)
	Info       Info                  `json:"info"`                 // API metadata
	Servers    []Server              `json:"servers,omitempty"`    // Server URLs
	Paths      map[string]*PathItem  `json:"paths"`                // API endpoints
	Components *Components           `json:"components,omitempty"` // Reusable components
	Security   []SecurityRequirement `json:"security,omitempty"`   // Global security
	Tags       []Tag                 `json:"tags,omitempty"`       // Endpoint tags
}

Spec represents an OpenAPI 3.0 specification document.

This is the root object of an OpenAPI 3.0 document, containing all metadata, paths, components, and security definitions.

Spec Structure:

  • OpenAPI: Version ("3.0.3")
  • Info: API metadata (title, version, description)
  • Servers: API server URLs (dev, staging, production)
  • Paths: All API endpoints and operations
  • Components: Reusable schemas, security schemes
  • Security: Global security requirements
  • Tags: Endpoint categorization

func NewSpec

func NewSpec(title, version, description string) *Spec

NewSpec creates a new OpenAPI 3.0 specification with default values.

func (*Spec) AddPath

func (s *Spec) AddPath(path string, item *PathItem)

AddPath adds or updates a path in the specification.

func (*Spec) AddSchema

func (s *Spec) AddSchema(name string, schema *Schema)

AddSchema adds a reusable schema component.

func (*Spec) AddSecurityScheme

func (s *Spec) AddSecurityScheme(name string, scheme *SecurityScheme)

AddSecurityScheme adds a security scheme component.

func (*Spec) AddTag

func (s *Spec) AddTag(tag Tag)

AddTag adds a tag to the specification.

func (*Spec) ToJSON

func (s *Spec) ToJSON() ([]byte, error)

ToJSON converts the spec to JSON bytes.

type Tag

type Tag struct {
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
}

Tag adds metadata to a single tag.

Jump to

Keyboard shortcuts

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