openapi

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Dec 9, 2025 License: Apache-2.0 Imports: 14 Imported by: 0

README

OpenAPI Package

Automatic OpenAPI 3.0.4 and 3.1.2 specification generation and Swagger UI integration for Rivaas.

This package enables automatic generation of OpenAPI specifications from Go code using struct tags and reflection. It integrates seamlessly with the Rivaas router to provide comprehensive API documentation with minimal boilerplate.

Features

  • Automatic Parameter Discovery - Extracts query, path, header, and cookie parameters from struct tags
  • Schema Generation - Converts Go types to OpenAPI schemas automatically
  • Swagger UI Integration - Built-in, customizable Swagger UI for interactive API documentation
  • Semantic Operation IDs - Auto-generates operation IDs from HTTP methods and paths
  • Security Schemes - Support for Bearer, API Key, OAuth2, and OpenID Connect
  • Version Support - Generate OpenAPI 3.0.4 or 3.1.2 specifications
  • Collision-Resistant Naming - Schema names use pkgname.TypeName format to prevent collisions
  • ETag-Based Caching - Spec serving with HTTP caching support
  • Concurrent Safe - Thread-safe operations for concurrent use

Quick Start

With Rivaas App Framework
package main

import (
    "rivaas.dev/app"
    "rivaas.dev/openapi"
)

func main() {
    app := app.New(
        app.WithServiceName("my-api"),
        app.WithOpenAPI(
            openapi.WithTitle("My API", "1.0.0"),
            openapi.WithDescription("API for managing users"),
            openapi.WithServer("http://localhost:8080", "Local development"),
            openapi.WithSwaggerUI(true, "/docs"),
        ),
    )

    app.GET("/users/:id", getUserHandler).
        Doc("Get user", "Retrieves a user by ID").
        Request(GetUserRequest{}).
        Response(200, UserResponse{}).
        Tags("users")

    app.Run()
}
Standalone Usage
package main

import (
    "rivaas.dev/openapi"
)

func main() {
    cfg := openapi.MustNew(
        openapi.WithTitle("My API", "1.0.0"),
        openapi.WithDescription("API description"),
        openapi.WithServer("http://localhost:8080", "Local development"),
    )

    manager := openapi.NewManager(cfg)
    
    manager.Register("GET", "/users/:id").
        Doc("Get user", "Retrieves a user by ID").
        Request(GetUserRequest{}).
        Response(200, UserResponse{})

    specJSON, _, err := manager.GenerateSpec()
    if err != nil {
        log.Fatal(err)
    }
    
    // Serve specJSON via HTTP or save to file
}

Configuration

Configuration is done exclusively through functional options. All configuration types are private to enforce this pattern.

Basic Configuration
cfg := openapi.MustNew(
    openapi.WithTitle("My API", "1.0.0"),
    openapi.WithDescription("API description"),
    openapi.WithSummary("Short summary"), // 3.1.2 only
    openapi.WithTermsOfService("https://example.com/terms"),
    openapi.WithVersion("3.1.2"), // or "3.0.4"
)
Servers
openapi.WithServer("https://api.example.com", "Production"),
openapi.WithServer("http://localhost:8080", "Local development"),

// With variables
openapi.WithServerVariable("baseUrl", "https://api.example.com", 
    []string{"https://api.example.com", "https://staging.example.com"},
    "Base URL for the API"),
Security Schemes
Bearer Authentication
openapi.WithBearerAuth("bearerAuth", "JWT authentication"),
API Key Authentication
openapi.WithAPIKey(
    "apiKey",
    "X-API-Key",
    openapi.ParameterLocationHeader,
    "API key for authentication",
),
OAuth2
openapi.WithOAuth2(
    "oauth2",
    "OAuth2 authentication",
    openapi.OAuth2Flow{
        Type:             openapi.FlowAuthorizationCode,
        AuthorizationUrl: "https://example.com/oauth/authorize",
        TokenUrl:         "https://example.com/oauth/token",
        Scopes: map[string]string{
            "read":  "Read access",
            "write": "Write access",
        },
    },
    openapi.OAuth2Flow{
        Type:     openapi.FlowClientCredentials,
        TokenUrl: "https://example.com/oauth/token",
        Scopes:   map[string]string{"read": "Read access"},
    },
),
OpenID Connect
openapi.WithOpenIDConnect(
    "openId",
    "https://example.com/.well-known/openid-configuration",
    "OpenID Connect authentication",
),
Tags
openapi.WithTag("users", "User management operations"),
openapi.WithTag("posts", "Post management operations"),
Swagger UI Configuration
openapi.WithSwaggerUI(true, "/docs"),

// UI Customization
openapi.WithUIDocExpansion(openapi.DocExpansionList),
openapi.WithUITryItOut(true),
openapi.WithUIRequestSnippets(true, 
    openapi.SnippetCurlBash,
    openapi.SnippetCurlPowerShell,
),
openapi.WithUISyntaxTheme(openapi.SyntaxThemeMonokai),

Route Documentation

The package provides a fluent API for documenting routes:

app.GET("/users/:id", handler).
    Doc("Get user", "Retrieves a user by ID").
    Summary("Get user").                    // Alternative to Doc
    Request(GetUserRequest{}).              // Request body/parameters
    Response(200, UserResponse{}).          // Success response
    Response(404, ErrorResponse{}).         // Error response
    Response(500, ErrorResponse{}).         // Error response
    Tags("users", "public").                // Tags
    OperationID("getUserById").             // Custom operation ID
    Security("bearerAuth").                 // Security requirement
    Deprecated()                            // Mark as deprecated
Request Documentation
type GetUserRequest struct {
    ID     int    `params:"id" doc:"User ID" example:"123"`
    Expand string `query:"expand" doc:"Fields to expand" enum:"profile,settings"`
    Format string `header:"Accept" doc:"Response format" enum:"json,xml"`
}

app.GET("/users/:id", handler).
    Request(GetUserRequest{})
Response Documentation
type UserResponse struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

type ErrorResponse struct {
    Code    int    `json:"code"`
    Message string `json:"message"`
}

app.GET("/users/:id", handler).
    Response(200, UserResponse{}).
    Response(404, ErrorResponse{}).
    Response(500, ErrorResponse{})
Security Requirements
// Single security scheme
app.GET("/users/:id", handler).
    Security("bearerAuth")

// OAuth2 with scopes
app.POST("/users", handler).
    Security("oauth2", "read", "write")

// Multiple security schemes (OR)
app.DELETE("/users/:id", handler).
    Security("bearerAuth").
    Security("apiKey")

Auto-Discovery

The package automatically discovers API parameters from struct tags compatible with the binding package.

Supported Tags
  • params:"name" - Path parameters (always required)
  • query:"name" - Query parameters
  • header:"name" - Header parameters
  • cookie:"name" - Cookie parameters
  • json:"name" - Request body fields
Additional Tags
  • doc:"description" - Parameter/field description
  • example:"value" - Example value
  • enum:"val1,val2" - Enum values (comma-separated)
  • validate:"required" - Validation rules (affects required in OpenAPI)
Struct Tag Examples
type CreateUserRequest struct {
    // Path parameter (always required)
    UserID int `params:"id" doc:"User ID" example:"123"`
    
    // Query parameters
    Page    int    `query:"page" doc:"Page number" example:"1" validate:"min=1"`
    PerPage int    `query:"per_page" doc:"Items per page" example:"20" validate:"min=1,max=100"`
    Format  string `query:"format" doc:"Response format" enum:"json,xml"`
    
    // Header parameters
    Accept string `header:"Accept" doc:"Content type" enum:"application/json,application/xml"`
    
    // Request body fields
    Name  string `json:"name" doc:"User name" example:"John Doe" validate:"required"`
    Email string `json:"email" doc:"User email" example:"john@example.com" validate:"required,email"`
    Age   *int   `json:"age,omitempty" doc:"User age" example:"30" validate:"min=0,max=150"`
}

type UpdateUserRequest struct {
    // Path parameter
    ID int `params:"id"`
    
    // Request body (pointer makes it optional)
    Name  *string `json:"name,omitempty" doc:"Updated name"`
    Email *string `json:"email,omitempty" doc:"Updated email"`
}

Schema Generation

Go types are automatically converted to OpenAPI schemas:

Supported Types
  • Primitives: string, int, int64, float64, bool
  • Pointers: *string (nullable, optional)
  • Slices: []string, []int
  • Maps: map[string]int
  • Structs: Custom types (become object schemas)
  • Time: time.Time (becomes string with date-time format)
  • Embedded Structs: Fields from embedded structs are included
Schema Naming

Component schema names use the format pkgname.TypeName to prevent cross-package collisions:

// In package "api"
type User struct { ... }  // Becomes "api.User"

// In package "models"
type User struct { ... }  // Becomes "models.User"
Schema Examples
type User struct {
    ID        int       `json:"id"`
    Name      string    `json:"name"`
    Email     string    `json:"email"`
    Tags      []string  `json:"tags"`
    Metadata  map[string]string `json:"metadata"`
    CreatedAt time.Time `json:"created_at"`
    UpdatedAt *time.Time `json:"updated_at,omitempty"`
}

type UserList struct {
    Users []User `json:"users"`
    Total int    `json:"total"`
}

Advanced Usage

Custom Operation IDs
app.GET("/users/:id", handler).
    OperationID("retrieveUser")
Extensions

Add custom x-* extensions to various parts of the spec:

// Info extensions
cfg := openapi.MustNew(
    openapi.WithInfoExtension("x-api-version", "v2"),
    openapi.WithInfoExtension("x-custom-feature", true),
)

// Server extensions
openapi.WithServerExtension("x-rate-limit", 1000)

// Tag extensions
openapi.WithTagExtension("x-priority", "high")
Version Selection
cfg := openapi.MustNew(
    openapi.WithVersion("3.1.2"), // or "3.0.4"
    openapi.WithStrictDownlevel(true), // Error on 3.1-only features in 3.0
)
Accessing Generated Spec
manager := openapi.NewManager(cfg)
// ... register routes ...

specJSON, etag, err := manager.GenerateSpec()
if err != nil {
    log.Fatal(err)
}

// Use specJSON (ETag for HTTP caching)
w.Header().Set("ETag", etag)
w.Header().Set("Content-Type", "application/json")
w.Write(specJSON)
Warnings

The package generates warnings when 3.1-only features are used with a 3.0 target:

specJSON, warnings, err := manager.GenerateSpec()
for _, warn := range warnings {
    log.Printf("Warning: %s at %s: %s", 
        warn.Code, warn.Path, warn.Message)
}

Swagger UI Customization

Common Options
openapi.WithSwaggerUI(true, "/docs"),

// Document expansion
openapi.WithUIDocExpansion(openapi.DocExpansionList),     // list, full, none
openapi.WithUIModelsExpandDepth(1),                       // How deep to expand models
openapi.WithUIModelExpandDepth(1),                        // How deep to expand model

// Display options
openapi.WithUIDisplayOperationID(true),                   // Show operation IDs
openapi.WithUIDefaultModelRendering(openapi.ModelRenderingExample), // example, model

// Try it out
openapi.WithUITryItOut(true),                            // Enable "Try it out"
openapi.WithUIRequestSnippets(true,                      // Show request snippets
    openapi.SnippetCurlBash,
    openapi.SnippetCurlPowerShell,
    openapi.SnippetCurlCmd,
),
openapi.WithUIRequestSnippetsExpanded(true),             // Expand snippets by default
openapi.WithUIDisplayRequestDuration(true),              // Show request duration

// Filtering and sorting
openapi.WithUIFilter(true),                              // Enable filter box
openapi.WithUIMaxDisplayedTags(10),                      // Limit displayed tags
openapi.WithUIOperationsSorter(openapi.OperationsSorterAlpha), // alpha, method
openapi.WithUITagsSorter(openapi.TagsSorterAlpha),      // alpha

// Syntax highlighting
openapi.WithUISyntaxHighlight(true),                     // Enable syntax highlighting
openapi.WithUISyntaxTheme(openapi.SyntaxThemeMonokai),  // agate, monokai, etc.

// Validation
openapi.WithUIValidator("https://validator.swagger.io/validator/debug"),

// Authentication persistence
openapi.WithUIPersistAuth(true),                         // Persist auth across refreshes
openapi.WithUIWithCredentials(true),                    // Send credentials with requests

Complete Example

package main

import (
    "rivaas.dev/app"
    "rivaas.dev/openapi"
    "time"
)

type User struct {
    ID        int       `json:"id"`
    Name      string    `json:"name"`
    Email     string    `json:"email"`
    CreatedAt time.Time `json:"created_at"`
}

type CreateUserRequest struct {
    Name  string `json:"name" validate:"required"`
    Email string `json:"email" validate:"required,email"`
}

type GetUserRequest struct {
    ID int `params:"id" doc:"User ID"`
}

func main() {
    app := app.New(
        app.WithServiceName("user-api"),
        app.WithOpenAPI(
            openapi.WithTitle("User API", "1.0.0"),
            openapi.WithDescription("API for managing users"),
            openapi.WithServer("http://localhost:8080", "Local development"),
            openapi.WithServer("https://api.example.com", "Production"),
            openapi.WithBearerAuth("bearerAuth", "JWT authentication"),
            openapi.WithTag("users", "User management operations"),
            openapi.WithSwaggerUI(true, "/docs"),
            openapi.WithUIDocExpansion(openapi.DocExpansionList),
            openapi.WithUITryItOut(true),
        ),
    )

    // GET /users/:id
    app.GET("/users/:id", getUserHandler).
        Doc("Get user", "Retrieves a user by ID").
        Request(GetUserRequest{}).
        Response(200, User{}).
        Response(404, ErrorResponse{}).
        Tags("users").
        Security("bearerAuth")

    // POST /users
    app.POST("/users", createUserHandler).
        Doc("Create user", "Creates a new user").
        Request(CreateUserRequest{}).
        Response(201, User{}).
        Response(400, ErrorResponse{}).
        Tags("users").
        Security("bearerAuth")

    app.Run()
}

API Reference

Full API documentation is available at pkg.go.dev/rivaas.dev/openapi.

Key Types
  • Config - OpenAPI configuration (created via New() or MustNew())
  • Manager - Manages spec generation and caching
  • RouteWrapper - Fluent API for route documentation
  • Option - Functional option for configuration
Key Functions
  • New(...Option) (*Config, error) - Create configuration
  • MustNew(...Option) *Config - Create configuration (panics on error)
  • NewManager(*Config) *Manager - Create manager instance
  • Manager.Register(method, path) *RouteWrapper - Register route
  • Manager.GenerateSpec() ([]byte, string, error) - Generate OpenAPI spec

Troubleshooting

Schema Name Collisions

If you have types with the same name in different packages, the package automatically prefixes schema names with the package name:

// api.User becomes "api.User"
// models.User becomes "models.User"
Extension Validation

Extension keys must start with x-. In OpenAPI 3.1.x, keys starting with x-oai- or x-oas- are reserved and will be filtered out.

Version Compatibility

When using OpenAPI 3.0.4, some 3.1.2 features are automatically down-leveled with warnings:

  • info.summary - Dropped (3.1-only)
  • license.identifier - Dropped (3.1-only)
  • const in schemas - Converted to enum with single value
  • webhooks - Dropped (3.1-only)
  • mutualTLS security - Dropped (3.1-only)

Enable StrictDownlevel to error instead of warn:

openapi.WithStrictDownlevel(true)
Concurrent Access

Manager and RouteWrapper are safe for concurrent use. However, RouteWrapper should be configured by a single goroutine before calling Freeze().

License

[Add license information here]

Documentation

Overview

Package openapi provides OpenAPI 3.0.4 and 3.1.2 specification generation and Swagger UI integration for Rivaas.

This package enables automatic generation of OpenAPI specifications from Go code using struct tags and reflection. It integrates seamlessly with the Rivaas router to provide comprehensive API documentation with minimal boilerplate.

Features

  • Automatic parameter discovery from struct tags (query, path, header, cookie)
  • Request/response body schema generation from Go types
  • Swagger UI integration with customizable appearance
  • Semantic operation ID generation based on HTTP method and path
  • Support for security schemes (Bearer, API Key, OAuth)
  • ETag-based caching for spec serving
  • Collision-resistant schema naming (pkgname.TypeName format)

Quick Start

import (
    "net/http"
    "rivaas.dev/openapi"
)

// Create OpenAPI configuration
cfg := openapi.MustNew(
    openapi.WithTitle("My API", "1.0.0"),
    openapi.WithDescription("API description"),
    openapi.WithBearerAuth("bearerAuth", "JWT authentication"),
    openapi.WithServer("http://localhost:8080", "Local development"),
    openapi.WithSwaggerUI(true, "/docs"),
)

// Create manager and register routes
manager := openapi.NewManager(cfg)
route := manager.Register("GET", "/users/:id")
route.Doc("Get user", "Retrieves a user by ID").
    Request(GetUserRequest{}).
    Response(200, UserResponse{}).
    Tags("users")

// Generate OpenAPI specification
specJSON, etag, err := manager.GenerateSpec()
if err != nil {
    log.Fatal(err)
}

// Serve the specification via HTTP (example)
http.HandleFunc(cfg.SpecPath, func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    w.Header().Set("ETag", etag)
    w.Write(specJSON)
})

Configuration

Configuration is done exclusively through functional options using New or MustNew. All UI configuration types are private to enforce this pattern and prevent direct struct initialization.

Auto-Discovery

The package automatically discovers API parameters from struct tags compatible with the binding package:

  • query: Query parameters
  • params: Path parameters
  • header: Header parameters
  • cookie: Cookie parameters
  • json: Request body fields

Example:

type GetUserRequest struct {
    ID    int    `path:"id" doc:"User ID" example:"123"`
    Expand string `query:"expand" doc:"Fields to expand" enum:"profile,settings"`
}

This automatically generates OpenAPI parameters without manual specification.

Schema Naming

Component schema names use the format "pkgname.TypeName" to prevent cross-package type name collisions. For example, types from different packages with the same name (e.g., "api.User" and "models.User") will generate distinct schema names in the OpenAPI specification.

The package name is extracted from the last component of the package path (e.g., "github.com/user/api" -> "api"). This ensures that types with the same name from different packages don't collide in the components/schemas section of the generated OpenAPI specification.

Operation IDs

Operation IDs are automatically generated from HTTP method and path using semantic naming:

  • GET /users -> getUsers
  • GET /users/:id -> getUserById
  • POST /users -> createUser
  • PATCH /users/:id -> updateUserById
  • PUT /users/:id -> replaceUserById

Custom operation IDs can be set using RouteWrapper.OperationID.

Index

Examples

Constants

View Source
const (
	// Version30 represents OpenAPI 3.0.4.
	Version30 = "3.0.4"
	// Version31 represents OpenAPI 3.1.2.
	Version31 = "3.1.2"
)

OpenAPI version constants.

Variables

This section is empty.

Functions

This section is empty.

Types

type Components

type Components struct {
	// Schemas maps schema names to Schema definitions.
	Schemas map[string]*Schema `json:"schemas,omitempty"`

	// SecuritySchemes maps security scheme names to SecurityScheme definitions.
	SecuritySchemes map[string]*SecurityScheme `json:"securitySchemes,omitempty"`
}

Components holds reusable components (schemas, security schemes, etc.).

Components allow definitions to be referenced multiple times, reducing duplication and improving spec maintainability.

type Config

type Config struct {
	// Info contains API metadata (title, version, description, contact, license).
	Info Info

	// Servers lists available server URLs for the API.
	Servers []Server

	// Tags provides additional metadata for operations.
	Tags []Tag

	// SecuritySchemes defines available authentication/authorization schemes.
	SecuritySchemes map[string]*SecurityScheme

	// DefaultSecurity applies security requirements to all operations by default.
	DefaultSecurity []SecurityRequirement

	// ExternalDocs provides external documentation links.
	ExternalDocs *ExternalDocs

	// Extensions contains specification extensions (fields prefixed with x-).
	// Extensions are added to the root of the OpenAPI specification.
	//
	// Direct mutation of this map after New/MustNew bypasses Config.Validate().
	// However, projection-time filtering via copyExtensions still applies:
	// - Keys must start with "x-"
	// - In OpenAPI 3.1.x, keys starting with "x-oai-" or "x-oas-" are reserved and will be filtered
	//
	// Prefer using WithExtension() option instead of direct mutation.
	Extensions map[string]any

	// Version is the target OpenAPI version.
	// Use Version30 or Version31 constants.
	// Default: Version30
	Version string

	// StrictDownlevel causes projection to error (instead of warn) when
	// 3.1-only features are used with a 3.0 target.
	// Default: false
	StrictDownlevel bool

	// SpecPath is the HTTP path where the OpenAPI specification JSON is served.
	// Default: "/openapi.json"
	SpecPath string

	// UIPath is the HTTP path where Swagger UI is served.
	// Default: "/docs"
	UIPath string

	// ServeUI enables or disables Swagger UI serving.
	// Default: true
	ServeUI bool
	// contains filtered or unexported fields
}

Config holds OpenAPI configuration. All fields are public for functional options, but direct modification after creation is not recommended. Use functional options to configure.

Create instances using New or MustNew.

func MustNew

func MustNew(opts ...Option) *Config

MustNew creates a new OpenAPI Config and panics if validation fails.

This is a convenience wrapper around New for use in package initialization or when configuration errors should cause immediate failure.

Example:

cfg := openapi.MustNew(
    openapi.WithTitle("My API", "1.0.0"),
    openapi.WithDescription("API description"),
)
Example

ExampleMustNew demonstrates creating OpenAPI configuration that panics on error.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	cfg := openapi.MustNew(
		openapi.WithTitle("My API", "1.0.0"),
		openapi.WithSwaggerUI(true, "/docs"),
	)

	fmt.Printf("UI enabled: %v\n", cfg.ServeUI)
}
Output:

UI enabled: true

func New

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

New creates a new OpenAPI Config with the given options.

It applies default values and validates the configuration. Returns an error if validation fails (e.g., missing title or version). Use Config.Validate to check validation rules.

Example:

cfg, err := openapi.New(
    openapi.WithTitle("My API", "1.0.0"),
    openapi.WithDescription("API description"),
    openapi.WithBearerAuth("bearerAuth", "JWT authentication"),
)
if err != nil {
    log.Fatal(err)
}
Example

ExampleNew demonstrates creating a new OpenAPI configuration.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	cfg, err := openapi.New(
		openapi.WithTitle("My API", "1.0.0"),
		openapi.WithDescription("API for managing users"),
		openapi.WithServer("http://localhost:8080", "Local development"),
	)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Title: %s, Version: %s\n", cfg.Info.Title, cfg.Info.Version)
}
Output:

Title: My API, Version: 1.0.0

func (*Config) Validate

func (c *Config) Validate() error

Validate checks if the Config is valid.

It ensures that required fields (title, version) are set and validates nested configurations like UI settings. Returns an error describing all validation failures.

Validation is automatically called by New and MustNew.

type ConstraintKind added in v0.2.0

type ConstraintKind uint8

ConstraintKind represents the type of constraint on a path parameter. These map directly to router.ConstraintKind values.

const (
	ConstraintNone     ConstraintKind = iota
	ConstraintInt                     // OpenAPI: type integer, format int64
	ConstraintFloat                   // OpenAPI: type number, format double
	ConstraintUUID                    // OpenAPI: type string, format uuid
	ConstraintRegex                   // OpenAPI: type string, pattern
	ConstraintEnum                    // OpenAPI: type string, enum
	ConstraintDate                    // OpenAPI: type string, format date
	ConstraintDateTime                // OpenAPI: type string, format date-time
)

type Contact

type Contact struct {
	// Name is the contact person or organization name.
	Name string `json:"name,omitempty"`

	// URL is the URL pointing to the contact information.
	URL string `json:"url,omitempty"`

	// Email is the email address of the contact.
	Email string `json:"email,omitempty"`

	// Extensions contains specification extensions (fields prefixed with x-).
	//
	// Direct mutation of this map after New/MustNew bypasses Config.Validate().
	// However, projection-time filtering via copyExtensions still applies:
	// - Keys must start with "x-"
	// - In OpenAPI 3.1.x, keys starting with "x-oai-" or "x-oas-" are reserved and will be filtered
	//
	// Prefer using helper options (e.g., WithContactExtension, WithLicenseExtension) instead of direct mutation.
	Extensions map[string]any `json:"-"`
}

Contact information for the API.

type DocExpansionMode

type DocExpansionMode string

DocExpansionMode controls the default expansion behavior of operations and tags in Swagger UI.

This setting determines how much of the API documentation is expanded by default when the Swagger UI page loads.

const (
	// DocExpansionList expands only tags by default, keeping operations collapsed.
	DocExpansionList DocExpansionMode = "list"

	// DocExpansionFull expands both tags and operations by default.
	DocExpansionFull DocExpansionMode = "full"

	// DocExpansionNone collapses everything by default, requiring manual expansion.
	DocExpansionNone DocExpansionMode = "none"
)

DocExpansion constants control default expansion of operations and tags.

type Encoding

type Encoding struct {
	// ContentType for encoding a specific property (comma-separated list).
	// Defaults depend on the property type (see OpenAPI spec).
	ContentType string `json:"contentType,omitempty"`

	// Headers provides additional headers for the part (multipart only).
	Headers map[string]*Header `json:"headers,omitempty"`

	// Style describes how the property value will be serialized.
	// Valid values: "form", "spaceDelimited", "pipeDelimited", "deepObject".
	Style string `json:"style,omitempty"`

	// Explode generates separate parameters for array/object values.
	// Default is true when style is "form", false otherwise.
	Explode bool `json:"explode,omitempty"`

	// AllowReserved allows reserved characters per RFC6570.
	// Default is false.
	AllowReserved bool `json:"allowReserved,omitempty"`
}

Encoding describes encoding for a single schema property.

Used with multipart and application/x-www-form-urlencoded media types. The key in the encoding map corresponds to a property name in the schema.

type Example

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

Example represents an OpenAPI Example Object. Used for both request body and response body examples. See: https://spec.openapis.org/oas/v3.1.0#example-object

func ExternalExample added in v0.2.0

func ExternalExample(name, url string, opts ...ExampleOption) Example

ExternalExample creates a named example pointing to an external URL.

Use this for:

  • Large examples that would bloat the spec
  • Examples in formats that can't be embedded (XML, binary)
  • Shared examples across multiple specs

Parameters:

  • name: Unique identifier
  • url: URL pointing to the example content
  • opts: Optional configuration (summary, description)

Usage:

openapi.ExternalExample("large-response", "https://api.example.com/examples/large.json")

openapi.ExternalExample("xml-example", "https://api.example.com/examples/user.xml",
    openapi.WithExampleSummary("XML format response"),
)

func NewExample added in v0.2.0

func NewExample(name string, value any, opts ...ExampleOption) Example

NewExample creates a named example with an inline value. Note: This is named NewExample instead of Example to avoid a naming conflict with the Example type. Go does not allow a type and function with the same name in the same package.

Parameters:

  • name: Unique identifier (used as key in OpenAPI examples map)
  • value: The example value (serialized to JSON in spec)
  • opts: Optional configuration (summary, description)

Usage:

openapi.NewExample("success", UserResponse{ID: 123, Name: "John"})

openapi.NewExample("admin", UserResponse{ID: 1, Role: "admin"},
    openapi.WithExampleSummary("Admin user response"),
)

func (Example) Description

func (e Example) Description() string

Description returns the detailed description.

func (Example) ExternalValue

func (e Example) ExternalValue() string

ExternalValue returns the URL to an external example.

func (Example) IsExternal added in v0.2.0

func (e Example) IsExternal() bool

IsExternal returns true if this example uses an external URL.

func (Example) Name added in v0.2.0

func (e Example) Name() string

Name returns the unique identifier for this example.

func (Example) Summary

func (e Example) Summary() string

Summary returns the short description.

func (Example) Value

func (e Example) Value() any

Value returns the inline example value.

type ExampleOption added in v0.2.0

type ExampleOption func(*Example)

ExampleOption is a functional option for configuring an Example.

func WithExampleDescription added in v0.2.0

func WithExampleDescription(description string) ExampleOption

WithExampleDescription sets a detailed description for the example. CommonMark syntax is supported for rich text formatting.

Usage:

openapi.NewExample("success", data,
    openapi.WithExampleDescription("Returns when the user ID exists and is active."),
)

func WithExampleSummary added in v0.2.0

func WithExampleSummary(summary string) ExampleOption

WithExampleSummary sets a short description for the example. This appears as the example title in Swagger UI.

Usage:

openapi.NewExample("success", data,
    openapi.WithExampleSummary("Successful response"),
)

type ExampleSpec added in v0.2.0

type ExampleSpec struct {
	// Summary provides a short summary of the example.
	Summary string `json:"summary,omitempty"`

	// Description provides a detailed description of the example.
	Description string `json:"description,omitempty"`

	// Value is the example value.
	Value any `json:"value,omitempty"`

	// ExternalValue is a URL pointing to an external example.
	ExternalValue string `json:"externalValue,omitempty"`
}

ExampleSpec represents an example value with optional description. This is the exported spec type. For API usage, see the example.Example type.

type ExternalDocs

type ExternalDocs struct {
	// Description provides a description of the target documentation (supports Markdown).
	Description string `json:"description,omitempty"`

	// URL is the URL/URI for the target documentation (required).
	URL string `json:"url"`

	// Extensions contains specification extensions (fields prefixed with x-).
	Extensions map[string]any `json:"-"`
}

ExternalDocs provides external documentation links.

type HTTPMethod

type HTTPMethod string

HTTPMethod represents an HTTP method that can be used in "Try it out" functionality.

This is used to configure which HTTP methods are supported for interactive API testing.

const (
	// MethodGet represents the HTTP GET method.
	MethodGet HTTPMethod = "get"

	// MethodPost represents the HTTP POST method.
	MethodPost HTTPMethod = "post"

	// MethodPut represents the HTTP PUT method.
	MethodPut HTTPMethod = "put"

	// MethodDelete represents the HTTP DELETE method.
	MethodDelete HTTPMethod = "delete"

	// MethodPatch represents the HTTP PATCH method.
	MethodPatch HTTPMethod = "patch"

	// MethodHead represents the HTTP HEAD method.
	MethodHead HTTPMethod = "head"

	// MethodOptions represents the HTTP OPTIONS method.
	MethodOptions HTTPMethod = "options"

	// MethodTrace represents the HTTP TRACE method.
	MethodTrace HTTPMethod = "trace"
)

HTTP method constants for "Try it out" configuration.

type Header struct {
	// Description provides documentation for the header.
	Description string `json:"description,omitempty"`

	// Required indicates if the header is mandatory.
	Required bool `json:"required,omitempty"`

	// Deprecated indicates that the header is deprecated and should be transitioned out.
	Deprecated bool `json:"deprecated,omitempty"`

	// Style describes how the header value will be serialized.
	// For headers, the only valid value is "simple" (default).
	Style string `json:"style,omitempty"`

	// Explode generates comma-separated values for array/object types.
	// Default is false.
	Explode bool `json:"explode,omitempty"`

	// Schema defines the header value type (for schema-based serialization).
	Schema *Schema `json:"schema,omitempty"`

	// Example provides an example value for the header.
	Example any `json:"example,omitempty"`

	// Examples provides multiple named example values.
	Examples map[string]*ExampleSpec `json:"examples,omitempty"`

	// Content defines the media type and schema (for content-based serialization).
	// The map MUST contain only one entry.
	Content map[string]*MediaType `json:"content,omitempty"`
}

Header represents a response header.

Headers follow a similar structure to Parameters but are specific to responses. Headers can use either schema-based or content-based serialization.

type Info

type Info struct {
	// Title is the API title (required).
	Title string `json:"title"`

	// Summary is a short summary of the API (OpenAPI 3.1+ only).
	// In 3.0 targets, this will be dropped with a warning.
	Summary string `json:"summary,omitempty"`

	// Description provides a detailed description of the API (supports Markdown).
	Description string `json:"description,omitempty"`

	// TermsOfService is a URL/URI for the Terms of Service.
	TermsOfService string `json:"termsOfService,omitempty"`

	// Version is the API version (required, e.g., "1.0.0").
	Version string `json:"version"`

	// Contact provides contact information for the API.
	Contact *Contact `json:"contact,omitempty"`

	// License provides license information for the API.
	License *License `json:"license,omitempty"`

	// Extensions contains specification extensions (fields prefixed with x-).
	//
	// Direct mutation of this map after New/MustNew bypasses Config.Validate().
	// However, projection-time filtering via copyExtensions still applies:
	// - Keys must start with "x-"
	// - In OpenAPI 3.1.x, keys starting with "x-oai-" or "x-oas-" are reserved and will be filtered
	//
	// Prefer using WithInfoExtension() option instead of direct mutation.
	Extensions map[string]any `json:"-"`
}

Info provides metadata about the API.

type License

type License struct {
	// Name is the license name (required, e.g., "MIT", "Apache 2.0").
	Name string `json:"name"`

	// Identifier is an SPDX license expression (OpenAPI 3.1+, e.g., "Apache-2.0").
	// Mutually exclusive with URL.
	Identifier string `json:"identifier,omitempty"`

	// URL is the URL to the license (OpenAPI 3.0, e.g., "https://www.apache.org/licenses/LICENSE-2.0.html").
	// Mutually exclusive with Identifier.
	URL string `json:"url,omitempty"`

	// Extensions contains specification extensions (fields prefixed with x-).
	//
	// Direct mutation of this map after New/MustNew bypasses Config.Validate().
	// However, projection-time filtering via copyExtensions still applies:
	// - Keys must start with "x-"
	// - In OpenAPI 3.1.x, keys starting with "x-oai-" or "x-oas-" are reserved and will be filtered
	//
	// Prefer using helper options (e.g., WithLicenseExtension) instead of direct mutation.
	Extensions map[string]any `json:"-"`
}

License information for the API.

type Link struct {
	// OperationRef references an operation using a JSON Pointer or relative reference.
	// Example: "#/paths/~1users~1{userId}/get"
	OperationRef string `json:"operationRef,omitempty"`

	// OperationID references an operation by its operationId.
	// This is an alternative to OperationRef when the operation is in the same document.
	OperationID string `json:"operationId,omitempty"`

	// Parameters to pass to the linked operation.
	// Keys are parameter names, values are expressions or values to use.
	Parameters map[string]any `json:"parameters,omitempty"`

	// RequestBody to use as the request body for the linked operation.
	RequestBody any `json:"requestBody,omitempty"`

	// Description of the link.
	Description string `json:"description,omitempty"`

	// Server to be used by the target operation.
	// If not specified, the server from the operation is used.
	Server *Server `json:"server,omitempty"`
}

Link represents a design-time link for a response.

Links allow you to define operations that can be followed from a response. This is useful for describing workflows and relationships between operations.

type Manager

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

Manager manages OpenAPI specification generation and caching.

It coordinates between route metadata and schema generation to provide a complete OpenAPI documentation solution.

Concurrency: Manager is safe for concurrent use. The Manager.Register method and Manager.GenerateSpec can be called from multiple goroutines safely. The manager uses internal locking to protect its state and cache.

Manager instances are created via NewManager and should not be constructed directly.

func NewManager

func NewManager(cfg *Config) *Manager

NewManager creates a new OpenAPI manager from configuration.

The manager is initialized with the provided Config and is ready to register routes and generate OpenAPI specifications. Returns nil if cfg is nil.

Example:

cfg := openapi.MustNew(
    openapi.WithTitle("My API", "1.0.0"),
    openapi.WithSwaggerUI(true, "/docs"),
)
manager := openapi.NewManager(cfg)
Example

ExampleNewManager demonstrates creating an OpenAPI manager.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	cfg := openapi.MustNew(
		openapi.WithTitle("My API", "1.0.0"),
		openapi.WithDescription("API documentation"),
	)

	manager := openapi.NewManager(cfg)
	if manager == nil {
		fmt.Println("Manager is nil")
		return
	}

	fmt.Println("Manager created successfully")
}
Output:

Manager created successfully

func (*Manager) GenerateSpec

func (m *Manager) GenerateSpec() ([]byte, string, error)

GenerateSpec generates the OpenAPI specification JSON.

This method:

  • Freezes all route wrappers to make metadata immutable
  • Builds the IR specification
  • Projects to the target OpenAPI version
  • Caches the result for subsequent calls

Returns the JSON bytes and ETag. The ETag can be used for HTTP caching. Use Manager.Warnings to retrieve warnings from the last generation.

Example:

specJSON, etag, err := manager.GenerateSpec()
if err != nil {
    log.Fatal(err)
}

func (*Manager) OnRouteAdded

func (m *Manager) OnRouteAdded(route any) *RouteWrapper

OnRouteAdded is called when a route is registered with the router. It creates a RouteWrapper for OpenAPI documentation. This enables automatic OpenAPI schema generation from typed route constraints.

The route parameter should be a *router.Route. We use an interface to avoid circular dependencies between openapi and router packages.

func (*Manager) Register

func (m *Manager) Register(method, path string) *RouteWrapper

Register registers a route with OpenAPI metadata.

This method creates and returns a RouteWrapper that allows adding OpenAPI documentation through a fluent API. The route is tracked internally for spec generation.

Panics if m is nil.

Example:

manager.Register(http.MethodGet, "/users/:id").
    Doc("Get user", "Retrieves a user by ID").
    Request(GetUserRequest{}).
    Response(200, UserResponse{})
Example

ExampleManager_Register demonstrates registering routes for OpenAPI documentation.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	cfg := openapi.MustNew(
		openapi.WithTitle("User API", "1.0.0"),
	)

	manager := openapi.NewManager(cfg)

	// Register a route
	route := manager.Register("GET", "/users/:id")
	route.Doc("Get user", "Retrieves a user by ID").
		Tags("users")

	fmt.Println("Route registered")
}
Output:

Route registered

func (*Manager) ServeUI

func (m *Manager) ServeUI() bool

ServeUI returns whether Swagger UI should be served.

func (*Manager) SpecPath

func (m *Manager) SpecPath() string

SpecPath returns the configured spec path (e.g., "/openapi.json").

func (*Manager) UIConfig

func (m *Manager) UIConfig() uiConfig

UIConfig returns the UI configuration for rendering Swagger UI.

This is a convenience method for integration layers that need to serve the Swagger UI.

func (*Manager) UIPath

func (m *Manager) UIPath() string

UIPath returns the configured UI path (e.g., "/docs").

func (*Manager) Warnings

func (m *Manager) Warnings() []export.Warning

Warnings returns warnings from the last successful spec generation.

Warnings are generated when 3.1-only features are used with a 3.0 target, or when features need to be down-leveled. Returns an empty slice if no warnings were generated or if the spec hasn't been generated yet.

This method is safe for concurrent use.

Example:

specJSON, _, err := manager.GenerateSpec()
if err != nil {
    log.Fatal(err)
}
warnings := manager.Warnings()
for _, w := range warnings {
    log.Warnf("OpenAPI warning [%s] at %s: %s", w.Code, w.Path, w.Message)
}

type MediaType

type MediaType struct {
	// Schema defines the structure of the content.
	Schema *Schema `json:"schema,omitempty"`

	// Example provides an example value for the content type.
	Example any `json:"example,omitempty"`

	// Examples provides multiple named example values (OpenAPI 3.1+, but works in 3.0 too).
	Examples map[string]*ExampleSpec `json:"examples,omitempty"`

	// Encoding defines encoding for specific schema properties.
	// Only applies to request bodies with multipart or application/x-www-form-urlencoded.
	Encoding map[string]*Encoding `json:"encoding,omitempty"`
}

MediaType provides schema and examples for a specific content type.

Used in both RequestBody and Response to define the structure of request/response bodies for a given content type (e.g., "application/json").

type ModelRenderingMode

type ModelRenderingMode string

ModelRenderingMode controls how schema models are initially displayed in Swagger UI.

Models can be shown as example values or as structured schema definitions.

const (
	// ModelRenderingExample shows example values for schema models.
	ModelRenderingExample ModelRenderingMode = "example"

	// ModelRenderingModel shows the structured schema definition.
	ModelRenderingModel ModelRenderingMode = "model"
)

ModelRendering constants control initial model display.

type OAuth2Flow

type OAuth2Flow struct {
	// Type specifies the OAuth2 flow type (implicit, password, clientCredentials, authorizationCode).
	Type OAuthFlowType

	// AuthorizationURL is required for implicit and authorizationCode flows.
	AuthorizationURL string

	// TokenURL is required for password, clientCredentials, and authorizationCode flows.
	TokenURL string

	// RefreshURL is optional for all flows.
	RefreshURL string

	// Scopes maps scope names to descriptions (required, can be empty).
	Scopes map[string]string
}

OAuth2Flow configures a single OAuth2 flow with explicit type.

type OAuthFlow

type OAuthFlow struct {
	// AuthorizationURL is the authorization URL (REQUIRED for implicit, authorizationCode).
	AuthorizationURL string `json:"authorizationUrl,omitempty"`

	// TokenURL is the token URL (REQUIRED for password, clientCredentials, authorizationCode).
	TokenURL string `json:"tokenUrl,omitempty"`

	// RefreshURL is the URL for obtaining refresh tokens (optional).
	RefreshURL string `json:"refreshUrl,omitempty"`

	// Scopes maps scope names to their descriptions (REQUIRED, can be empty).
	Scopes map[string]string `json:"scopes"`
}

OAuthFlow contains configuration details for a supported OAuth Flow.

type OAuthFlowType

type OAuthFlowType string

OAuthFlowType represents the type of OAuth2 flow.

const (
	// FlowImplicit represents the OAuth2 implicit flow.
	FlowImplicit OAuthFlowType = "implicit"
	// FlowPassword represents the OAuth2 resource owner password flow.
	FlowPassword OAuthFlowType = "password"
	// FlowClientCredentials represents the OAuth2 client credentials flow.
	FlowClientCredentials OAuthFlowType = "clientCredentials"
	// FlowAuthorizationCode represents the OAuth2 authorization code flow.
	FlowAuthorizationCode OAuthFlowType = "authorizationCode"
)

type OAuthFlows

type OAuthFlows struct {
	// Implicit configuration for the OAuth Implicit flow.
	Implicit *OAuthFlow `json:"implicit,omitempty"`

	// Password configuration for the OAuth Resource Owner Password flow.
	Password *OAuthFlow `json:"password,omitempty"`

	// ClientCredentials configuration for the OAuth Client Credentials flow.
	ClientCredentials *OAuthFlow `json:"clientCredentials,omitempty"`

	// AuthorizationCode configuration for the OAuth Authorization Code flow.
	AuthorizationCode *OAuthFlow `json:"authorizationCode,omitempty"`
}

OAuthFlows allows configuration of the supported OAuth Flows.

At least one flow must be configured for OAuth2 security schemes.

type Operation

type Operation struct {
	// Tags groups operations for organization in Swagger UI.
	Tags []string `json:"tags,omitempty"`

	// Summary is a brief, one-line description of the operation.
	Summary string `json:"summary,omitempty"`

	// Description provides detailed information about the operation (supports Markdown).
	Description string `json:"description,omitempty"`

	// OperationID is a unique identifier for the operation (used by code generators).
	OperationID string `json:"operationId,omitempty"`

	// Parameters lists query, path, header, and cookie parameters.
	Parameters []Parameter `json:"parameters,omitempty"`

	// RequestBody describes the request body schema (for POST, PUT, PATCH).
	RequestBody *RequestBody `json:"requestBody,omitempty"`

	// Responses maps HTTP status codes to response definitions.
	Responses map[string]*Response `json:"responses"`

	// Deprecated marks the operation as deprecated.
	Deprecated bool `json:"deprecated,omitempty"`

	// Security overrides global security requirements for this operation.
	Security []SecurityRequirement `json:"security,omitempty"`
}

Operation describes a single API operation on a path.

An operation represents a single HTTP method on a path and contains all information needed to document and interact with that endpoint.

type OperationsSorterMode

type OperationsSorterMode string

OperationsSorterMode controls how operations are sorted within each tag in Swagger UI.

Operations can be sorted alphabetically by path, by HTTP method, or left in server order.

const (
	// OperationsSorterAlpha sorts operations alphabetically by path.
	OperationsSorterAlpha OperationsSorterMode = "alpha"

	// OperationsSorterMethod sorts operations by HTTP method.
	OperationsSorterMethod OperationsSorterMode = "method"

	// OperationsSorterNone uses server order without sorting.
	OperationsSorterNone OperationsSorterMode = ""
)

OperationsSorter constants control operation sorting within tags.

type Option

type Option func(*Config)

Option configures OpenAPI behavior using the functional options pattern. Options are applied in order, with later options potentially overriding earlier ones.

func WithAPIKey

func WithAPIKey(name, paramName string, in ParameterLocation, desc string) Option

WithAPIKey adds API key authentication scheme.

Parameters:

  • name: Scheme name used in security requirements
  • paramName: Name of the header/query parameter (e.g., "X-API-Key")
  • in: Location of the API key - use InHeader, InQuery, or InCookie
  • desc: Description shown in Swagger UI

Example:

openapi.WithAPIKey("apiKey", "X-API-Key", openapi.InHeader, "API key in X-API-Key header")

func WithBearerAuth

func WithBearerAuth(name, desc string) Option

WithBearerAuth adds Bearer (JWT) authentication scheme.

The name is used to reference this scheme in security requirements. The description appears in Swagger UI to help users understand the authentication.

Example:

openapi.WithBearerAuth("bearerAuth", "JWT token authentication. Format: Bearer <token>")

Then use in routes:

app.GET("/protected", handler).Bearer()
Example

ExampleWithBearerAuth demonstrates configuring Bearer authentication.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	cfg := openapi.MustNew(
		openapi.WithTitle("My API", "1.0.0"),
		openapi.WithBearerAuth("bearerAuth", "JWT authentication"),
	)

	fmt.Printf("Security schemes: %d\n", len(cfg.SecuritySchemes))
}
Output:

Security schemes: 1

func WithContact

func WithContact(name, url, email string) Option

WithContact sets contact information for the API.

All parameters are optional. Empty strings are omitted from the specification.

Example:

openapi.WithContact("API Support", "https://example.com/support", "support@example.com")

func WithDefaultSecurity

func WithDefaultSecurity(scheme string, scopes ...string) Option

WithDefaultSecurity sets default security requirements applied to all operations.

Operations can override this by specifying their own security requirements using RouteWrapper.Security() or RouteWrapper.Bearer().

Example:

// Apply Bearer auth to all operations by default
openapi.WithDefaultSecurity("bearerAuth")

// Apply OAuth with specific scopes
openapi.WithDefaultSecurity("oauth2", "read", "write")

func WithDescription

func WithDescription(desc string) Option

WithDescription sets the API description.

The description supports Markdown formatting and appears in the OpenAPI spec and Swagger UI.

Example:

openapi.WithDescription("A RESTful API for managing users and their profiles.")

func WithExtension

func WithExtension(key string, value any) Option

WithExtension adds a specification extension to the root OpenAPI specification.

Extension keys MUST start with "x-". In OpenAPI 3.1.x, keys starting with "x-oai-" or "x-oas-" are reserved for the OpenAPI Initiative.

The value can be any valid JSON value (null, primitive, array, or object). Validation of extension keys happens during Config.Validate().

Example:

openapi.WithExtension("x-internal-id", "api-v2")
openapi.WithExtension("x-code-samples", []map[string]any{
    {"lang": "curl", "source": "curl https://api.example.com/users"},
})

func WithExternalDocs

func WithExternalDocs(url, description string) Option

WithExternalDocs sets external documentation URL and optional description.

func WithInfoExtension

func WithInfoExtension(key string, value any) Option

WithInfoExtension adds a specification extension to the Info object.

Extension keys must start with "x-". In OpenAPI 3.1.x, keys starting with "x-oai-" or "x-oas-" are reserved and cannot be used.

Example:

openapi.WithInfoExtension("x-api-category", "public")

func WithLicense

func WithLicense(name, url string) Option

WithLicense sets license information for the API using a URL (OpenAPI 3.0 style).

The name is required. URL is optional. This is mutually exclusive with identifier - use WithLicenseIdentifier for SPDX identifiers. Validation occurs when New() is called.

Example:

openapi.WithLicense("MIT", "https://opensource.org/licenses/MIT")

func WithLicenseIdentifier

func WithLicenseIdentifier(name, identifier string) Option

WithLicenseIdentifier sets license information for the API using an SPDX identifier (OpenAPI 3.1+).

The name is required. Identifier is an SPDX license expression (e.g., "Apache-2.0"). This is mutually exclusive with URL - use WithLicense for URL-based licenses. Validation occurs when New() is called.

Example:

openapi.WithLicenseIdentifier("Apache 2.0", "Apache-2.0")

func WithOAuth2

func WithOAuth2(name, desc string, flows ...OAuth2Flow) Option

WithOAuth2 adds OAuth2 authentication scheme.

At least one flow must be configured. Use OAuth2Flow to configure each flow type. Multiple flows can be provided to support different OAuth2 flow types.

Example:

openapi.WithOAuth2("oauth2", "OAuth2 authentication",
	openapi.OAuth2Flow{
		Type:             openapi.FlowAuthorizationCode,
		AuthorizationURL: "https://example.com/oauth/authorize",
		TokenURL:         "https://example.com/oauth/token",
		Scopes: map[string]string{
			"read":  "Read access",
			"write": "Write access",
		},
	},
	openapi.OAuth2Flow{
		Type:     openapi.FlowClientCredentials,
		TokenUrl: "https://example.com/oauth/token",
		Scopes:   map[string]string{"read": "Read access"},
	},
)

func WithOpenIDConnect

func WithOpenIDConnect(name, url, desc string) Option

WithOpenIDConnect adds OpenID Connect authentication scheme.

Parameters:

  • name: Scheme name used in security requirements
  • url: Well-known URL to discover OpenID Connect provider metadata
  • desc: Description shown in Swagger UI

Example:

openapi.WithOpenIDConnect("oidc", "https://example.com/.well-known/openid-configuration", "OpenID Connect authentication")

func WithServer

func WithServer(url, desc string) Option

WithServer adds a server URL to the specification.

Multiple servers can be added by calling this option multiple times. The description is optional and helps distinguish between environments.

Example:

openapi.WithServer("https://api.example.com", "Production"),
openapi.WithServer("https://staging-api.example.com", "Staging"),
Example

ExampleWithServer demonstrates adding server URLs.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	cfg := openapi.MustNew(
		openapi.WithTitle("My API", "1.0.0"),
		openapi.WithServer("http://localhost:8080", "Local development"),
		openapi.WithServer("https://api.example.com", "Production"),
	)

	fmt.Printf("Servers: %d\n", len(cfg.Servers))
}
Output:

Servers: 2

func WithServerVariable

func WithServerVariable(name, defaultValue string, enum []string, description string) Option

WithServerVariable adds a variable to the last added server for URL template substitution.

The variable name should match a placeholder in the server URL (e.g., {username}). Default is required. Enum and description are optional.

IMPORTANT: WithServerVariable must be called AFTER WithServer. It applies to the most recently added server. Validation occurs when New() is called.

Example:

openapi.WithServer("https://{username}.example.com:{port}/v1", "Multi-tenant API"),
openapi.WithServerVariable("username", "demo", []string{"demo", "prod"}, "User subdomain"),
openapi.WithServerVariable("port", "8443", []string{"8443", "443"}, "Server port"),

func WithSpecPath

func WithSpecPath(path string) Option

WithSpecPath sets the HTTP path where the OpenAPI specification JSON is served.

Default: "/openapi.json"

Example:

openapi.WithSpecPath("/api/openapi.json")

func WithStrictDownlevel

func WithStrictDownlevel(strict bool) Option

WithStrictDownlevel causes projection to error (instead of warn) when 3.1-only features are used with a 3.0 target.

Default: false (warnings only)

Example:

openapi.WithStrictDownlevel(true)

func WithSummary

func WithSummary(summary string) Option

WithSummary sets the API summary (OpenAPI 3.1+ only). In 3.0 targets, this will be dropped with a warning.

func WithSwaggerUI

func WithSwaggerUI(enabled bool, path ...string) Option

WithSwaggerUI enables or disables Swagger UI and optionally sets its path.

If enabled (default), Swagger UI is served at the configured UIPath. The path parameter is optional - if not provided, uses the default "/docs".

Example:

// Enable with default path (/docs)
openapi.WithSwaggerUI(true)

// Enable with custom path
openapi.WithSwaggerUI(true, "/swagger")

// Disable Swagger UI
openapi.WithSwaggerUI(false)
Example

ExampleWithSwaggerUI demonstrates enabling Swagger UI.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	cfg := openapi.MustNew(
		openapi.WithTitle("My API", "1.0.0"),
		openapi.WithSwaggerUI(true, "/docs"),
	)

	fmt.Printf("UI enabled: %v, UI path: %s\n", cfg.ServeUI, cfg.UIPath)
}
Output:

UI enabled: true, UI path: /docs

func WithTag

func WithTag(name, desc string) Option

WithTag adds a tag to the specification.

Tags are used to group operations in Swagger UI. Operations can be assigned tags using RouteWrapper.Tags(). Multiple tags can be added by calling this option multiple times.

Example:

openapi.WithTag("users", "User management operations"),
openapi.WithTag("orders", "Order processing operations"),
Example

ExampleWithTag demonstrates adding API tags.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	cfg := openapi.MustNew(
		openapi.WithTitle("My API", "1.0.0"),
		openapi.WithTag("users", "User management operations"),
		openapi.WithTag("orders", "Order management operations"),
	)

	fmt.Printf("Tags: %d\n", len(cfg.Tags))
}
Output:

Tags: 2

func WithTermsOfService

func WithTermsOfService(url string) Option

WithTermsOfService sets the Terms of Service URL/URI.

func WithTitle

func WithTitle(title, version string) Option

WithTitle sets the API title and version.

Both title and version are required. If not set, defaults to "API" and "1.0.0".

Example:

openapi.WithTitle("User Management API", "2.1.0")

func WithUIDeepLinking

func WithUIDeepLinking(enabled bool) Option

WithUIDeepLinking enables or disables deep linking in Swagger UI.

When enabled, Swagger UI updates the browser URL when operations are expanded, allowing direct linking to specific operations. Default: true.

Example:

openapi.WithUIDeepLinking(true)

func WithUIDefaultModelRendering

func WithUIDefaultModelRendering(mode ModelRenderingMode) Option

WithUIDefaultModelRendering sets the initial model display mode.

Valid modes:

  • ModelRenderingExample: Show example value (default)
  • ModelRenderingModel: Show model structure

Example:

openapi.WithUIDefaultModelRendering(openapi.ModelRenderingModel)

func WithUIDisplayOperationID

func WithUIDisplayOperationID(show bool) Option

WithUIDisplayOperationID shows or hides operation IDs in Swagger UI.

Operation IDs are useful for code generation and API client libraries. Default: false.

Example:

openapi.WithUIDisplayOperationID(true)

func WithUIDisplayRequestDuration

func WithUIDisplayRequestDuration(show bool) Option

WithUIDisplayRequestDuration shows or hides request duration in Swagger UI.

When enabled, the time taken for "Try it out" requests is displayed. Default: true.

Example:

openapi.WithUIDisplayRequestDuration(true)

func WithUIDocExpansion

func WithUIDocExpansion(mode DocExpansionMode) Option

WithUIDocExpansion sets the default expansion level for operations and tags.

Valid modes:

  • DocExpansionList: Expand only tags (default)
  • DocExpansionFull: Expand tags and operations
  • DocExpansionNone: Collapse everything

Example:

openapi.WithUIDocExpansion(openapi.DocExpansionFull)

func WithUIFilter

func WithUIFilter(enabled bool) Option

WithUIFilter enables or disables the operation filter/search box.

When enabled, users can filter operations by typing in a search box. Default: false.

Example:

openapi.WithUIFilter(true)

func WithUIMaxDisplayedTags

func WithUIMaxDisplayedTags(max int) Option

WithUIMaxDisplayedTags limits the number of tags displayed in Swagger UI.

When set to a positive number, only the first N tags are shown. Remaining tags are hidden. Use 0 or negative to show all tags. Default: 0 (show all).

Example:

openapi.WithUIMaxDisplayedTags(10) // Show only first 10 tags

func WithUIModelExpandDepth

func WithUIModelExpandDepth(depth int) Option

WithUIModelExpandDepth sets the default expansion depth for model example sections.

Controls how many levels of the example value are expanded. Default: 1.

Example:

openapi.WithUIModelExpandDepth(3)

func WithUIModelsExpandDepth

func WithUIModelsExpandDepth(depth int) Option

WithUIModelsExpandDepth sets the default expansion depth for model schemas.

Depth controls how many levels of nested properties are expanded by default. Use -1 to hide models completely. Default: 1.

Example:

openapi.WithUIModelsExpandDepth(2) // Expand 2 levels deep

func WithUIOperationsSorter

func WithUIOperationsSorter(mode OperationsSorterMode) Option

WithUIOperationsSorter sets how operations are sorted within tags.

Valid modes:

  • OperationsSorterAlpha: Sort alphabetically by path
  • OperationsSorterMethod: Sort by HTTP method (GET, POST, etc.)
  • OperationsSorterNone: Use server order (no sorting, default)

Example:

openapi.WithUIOperationsSorter(openapi.OperationsSorterAlpha)

func WithUIPersistAuth

func WithUIPersistAuth(enabled bool) Option

WithUIPersistAuth enables or disables authorization persistence.

When enabled, authorization tokens are persisted in browser storage and automatically included in subsequent requests. Default: false.

Example:

openapi.WithUIPersistAuth(true)

func WithUIRequestSnippets

func WithUIRequestSnippets(enabled bool, languages ...RequestSnippetLanguage) Option

WithUIRequestSnippets enables or disables code snippet generation.

When enabled, Swagger UI generates code snippets showing how to call the API in various languages (curl, etc.). The languages parameter specifies which snippet generators to include. If not provided, defaults to curl_bash.

Example:

openapi.WithUIRequestSnippets(true, openapi.SnippetCurlBash, openapi.SnippetCurlPowerShell)

func WithUIRequestSnippetsExpanded

func WithUIRequestSnippetsExpanded(expanded bool) Option

WithUIRequestSnippetsExpanded sets whether request snippets are expanded by default.

When true, code snippets are shown immediately without requiring user interaction. Default: false.

Example:

openapi.WithUIRequestSnippetsExpanded(true)

func WithUIShowCommonExtensions

func WithUIShowCommonExtensions(show bool) Option

WithUIShowCommonExtensions shows or hides common JSON Schema extensions.

When enabled, displays schema constraints like pattern, maxLength, minLength, etc. in the UI. Default: false.

Example:

openapi.WithUIShowCommonExtensions(true)

func WithUIShowExtensions

func WithUIShowExtensions(show bool) Option

WithUIShowExtensions shows or hides vendor extensions (x-* fields) in Swagger UI.

Vendor extensions are custom fields prefixed with "x-" in the OpenAPI spec. Default: false.

Example:

openapi.WithUIShowExtensions(true)

func WithUISupportedMethods

func WithUISupportedMethods(methods ...HTTPMethod) Option

WithUISupportedMethods sets which HTTP methods have "Try it out" enabled.

By default, all standard HTTP methods support "Try it out". Use this option to restrict which methods can be tested interactively in Swagger UI.

Example:

openapi.WithUISupportedMethods(openapi.MethodGet, openapi.MethodPost)

func WithUISyntaxHighlight

func WithUISyntaxHighlight(enabled bool) Option

WithUISyntaxHighlight enables or disables syntax highlighting in Swagger UI.

When enabled, request/response examples and code snippets are syntax-highlighted using the configured theme. Default: true.

Example:

openapi.WithUISyntaxHighlight(true)

func WithUISyntaxTheme

func WithUISyntaxTheme(theme SyntaxTheme) Option

WithUISyntaxTheme sets the syntax highlighting theme for code examples.

Available themes: Agate, Arta, Monokai, Nord, Obsidian, TomorrowNight, Idea. Default: Agate.

Example:

openapi.WithUISyntaxTheme(openapi.SyntaxThemeMonokai)

func WithUITagsSorter

func WithUITagsSorter(mode TagsSorterMode) Option

WithUITagsSorter sets how tags are sorted in Swagger UI.

Valid modes:

  • TagsSorterAlpha: Sort tags alphabetically
  • TagsSorterNone: Use server order (no sorting, default)

Example:

openapi.WithUITagsSorter(openapi.TagsSorterAlpha)

func WithUITryItOut

func WithUITryItOut(enabled bool) Option

WithUITryItOut enables or disables "Try it out" functionality by default.

When enabled, the "Try it out" button is automatically expanded for all operations. Default: true.

Example:

openapi.WithUITryItOut(false) // Require users to click "Try it out"

func WithUIValidator

func WithUIValidator(url string) Option

WithUIValidator sets the OpenAPI specification validator URL.

Swagger UI can validate your OpenAPI spec against a validator service. Use an empty string or "none" to disable validation. Default: uses Swagger UI's default validator.

Example:

openapi.WithUIValidator("https://validator.swagger.io/validator")
openapi.WithUIValidator("") // Disable validation

func WithUIWithCredentials

func WithUIWithCredentials(enabled bool) Option

WithUIWithCredentials enables or disables credentials in CORS requests.

When enabled, cookies and authorization headers are included in cross-origin requests. Only enable if your API server is configured to accept credentials. Default: false.

Example:

openapi.WithUIWithCredentials(true)

func WithVersion

func WithVersion(version string) Option

WithVersion sets the target OpenAPI version.

Use Version30 or Version31 constants. Default: Version30

Example:

openapi.WithVersion(openapi.Version31)

type ParamSpec

type ParamSpec = schema.ParamSpec

ParamSpec describes a single parameter extracted from struct tags.

This is a type alias for the internal schema.ParamSpec type. It's exported here for use in RequestMetadata.

type Parameter

type Parameter struct {
	// Name is the parameter name (required).
	Name string `json:"name"`

	// In is the parameter location: "query", "path", "header", or "cookie" (required).
	In string `json:"in"`

	// Description provides documentation for the parameter.
	Description string `json:"description,omitempty"`

	// Required indicates if the parameter is required (always true for path parameters).
	Required bool `json:"required,omitempty"`

	// Deprecated indicates that the parameter is deprecated and should be transitioned out.
	Deprecated bool `json:"deprecated,omitempty"`

	// AllowEmptyValue allows clients to pass a zero-length string value in place of parameters
	// that would otherwise be omitted. Valid only for query parameters.
	AllowEmptyValue bool `json:"allowEmptyValue,omitempty"`

	// Style describes how the parameter value will be serialized.
	// Defaults: "form" for query/cookie, "simple" for path/header.
	Style string `json:"style,omitempty"`

	// Explode when true, generates separate parameters for each value of arrays or
	// key-value pairs of objects. Default: true for "form" style, false otherwise.
	Explode bool `json:"explode,omitempty"`

	// AllowReserved when true, uses reserved expansion (RFC6570) allowing reserved characters
	// to pass through unchanged. Only applies to query parameters.
	AllowReserved bool `json:"allowReserved,omitempty"`

	// Schema defines the parameter type and validation rules (mutually exclusive with Content).
	Schema *Schema `json:"schema,omitempty"`

	// Example provides an example value for the parameter.
	Example any `json:"example,omitempty"`

	// Examples provides multiple examples keyed by name (mutually exclusive with Example).
	Examples map[string]*ExampleSpec `json:"examples,omitempty"`

	// Content defines the media type and schema for complex serialization
	// (mutually exclusive with Schema). The map MUST contain only one entry.
	Content map[string]*MediaType `json:"content,omitempty"`
}

Parameter describes a single operation parameter.

Parameters can be in query, path, header, or cookie locations.

type ParameterLocation

type ParameterLocation string

ParameterLocation represents where an API parameter can be located.

const (
	// InHeader indicates the parameter is passed in the HTTP header.
	InHeader ParameterLocation = "header"

	// InQuery indicates the parameter is passed as a query string parameter.
	InQuery ParameterLocation = "query"

	// InCookie indicates the parameter is passed as a cookie.
	InCookie ParameterLocation = "cookie"
)

type PathConstraint added in v0.2.0

type PathConstraint struct {
	Kind    ConstraintKind
	Pattern string   // for ConstraintRegex
	Enum    []string // for ConstraintEnum
}

PathConstraint describes a typed constraint for a path parameter. These constraints map directly to OpenAPI schema types.

type PathItem

type PathItem struct {
	// Summary provides a brief description of the path.
	Summary string `json:"summary,omitempty"`

	// Description provides detailed information about the path.
	Description string `json:"description,omitempty"`

	// Get is the GET operation for this path.
	Get *Operation `json:"get,omitempty"`

	// Put is the PUT operation for this path.
	Put *Operation `json:"put,omitempty"`

	// Post is the POST operation for this path.
	Post *Operation `json:"post,omitempty"`

	// Delete is the DELETE operation for this path.
	Delete *Operation `json:"delete,omitempty"`

	// Options is the OPTIONS operation for this path.
	Options *Operation `json:"options,omitempty"`

	// Head is the HEAD operation for this path.
	Head *Operation `json:"head,omitempty"`

	// Patch is the PATCH operation for this path.
	Patch *Operation `json:"patch,omitempty"`

	// Parameters are path-level parameters that apply to all operations.
	Parameters []Parameter `json:"parameters,omitempty"`
}

PathItem represents the operations available on a single path.

Each HTTP method (GET, POST, etc.) can have its own Operation. Path-level parameters apply to all operations on that path.

type RequestBody

type RequestBody struct {
	// Description provides documentation for the request body.
	Description string `json:"description,omitempty"`

	// Required indicates if the request body is required.
	Required bool `json:"required,omitempty"`

	// Content maps content types (e.g., "application/json") to MediaType definitions.
	Content map[string]*MediaType `json:"content"`
}

RequestBody describes a single request body.

Request bodies are used for POST, PUT, and PATCH operations.

type RequestMetadata

type RequestMetadata = schema.RequestMetadata

RequestMetadata contains auto-discovered information about a request struct.

This is a type alias for the internal schema.RequestMetadata type. It's exported here for use in RouteDoc.

type RequestSnippetLanguage

type RequestSnippetLanguage string

RequestSnippetLanguage defines the language for generated request code snippets.

These snippets help users understand how to make API calls using different tools.

const (
	// SnippetCurlBash generates curl commands for bash/sh shells.
	SnippetCurlBash RequestSnippetLanguage = "curl_bash"

	// SnippetCurlPowerShell generates curl commands for PowerShell.
	SnippetCurlPowerShell RequestSnippetLanguage = "curl_powershell"

	// SnippetCurlCmd generates curl commands for Windows CMD.
	SnippetCurlCmd RequestSnippetLanguage = "curl_cmd"
)

Request snippet language constants.

type RequestSnippetsConfig

type RequestSnippetsConfig struct {
	// Languages specifies which snippet languages to generate.
	// If empty, all available languages are included.
	Languages []RequestSnippetLanguage

	// DefaultExpanded determines if snippet sections are expanded by default.
	DefaultExpanded bool
}

RequestSnippetsConfig controls code snippet generation for API requests.

type Response

type Response struct {
	// Description describes the response (required).
	Description string `json:"description"`

	// Content maps content types (e.g., "application/json") to MediaType definitions.
	Content map[string]*MediaType `json:"content,omitempty"`

	// Headers defines response headers.
	Headers map[string]*Header `json:"headers,omitempty"`

	// Links defines operations that can be followed from the response.
	Links map[string]*Link `json:"links,omitempty"`
}

Response describes a single response from an API operation.

Each HTTP status code can have its own Response definition.

type RouteDoc

type RouteDoc struct {
	Summary               string
	Description           string
	OperationID           string
	Tags                  []string
	Deprecated            bool
	Consumes              []string
	Produces              []string
	RequestType           reflect.Type
	RequestMetadata       *RequestMetadata
	RequestExample        any               // Single unnamed example (uses "example" field)
	RequestNamedExamples  []example.Example // Named examples (uses "examples" field)
	ResponseTypes         map[int]reflect.Type
	ResponseExample       map[int]any               // Single unnamed example per status
	ResponseNamedExamples map[int][]example.Example // Named examples per status
	Security              []SecurityReq
}

RouteDoc holds all OpenAPI metadata for a route.

This struct is immutable after RouteWrapper.Freeze is called. It contains all information needed to generate an OpenAPI Operation specification.

type RouteInfo

type RouteInfo struct {
	Method          string                    // HTTP method (GET, POST, etc.)
	Path            string                    // URL path with parameters (e.g. "/users/:id")
	PathConstraints map[string]PathConstraint // Typed constraints for path parameters
}

RouteInfo contains basic route information needed for OpenAPI generation. This is framework-agnostic and replaces router.RouteInfo.

type RouteWrapper

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

RouteWrapper wraps route information with OpenAPI metadata.

It provides a fluent API for adding OpenAPI documentation to routes.

Concurrency: RouteWrapper is NOT safe for concurrent use during configuration. Each wrapper should be configured by a single goroutine. After calling RouteWrapper.Freeze, the wrapper becomes read-only and is safe for concurrent reads. The wrapper uses internal locking to protect its mutable state.

func NewRoute

func NewRoute(method, path string) *RouteWrapper

NewRoute creates a new RouteWrapper for the given route information.

The wrapper starts with default values and can be configured using the fluent API methods.

Example:

route := openapi.NewRoute("GET", "/users/:id")
route.Doc("Get user", "Retrieves a user by ID")

func NewRouteWithConstraints added in v0.2.0

func NewRouteWithConstraints(method, path string, constraints map[string]PathConstraint) *RouteWrapper

NewRouteWithConstraints creates a new RouteWrapper with typed path constraints.

The constraints map parameter names to their type constraints, which are used to generate proper OpenAPI schema types for path parameters.

Example:

constraints := map[string]PathConstraint{
    "id": {Kind: ConstraintInt},
}
route := openapi.NewRouteWithConstraints("GET", "/users/:id", constraints)

func (*RouteWrapper) Bearer

func (rw *RouteWrapper) Bearer() *RouteWrapper

Bearer adds Bearer (JWT) authentication requirement to the operation.

This is a convenience method that calls Security("bearerAuth"). The security scheme must be defined in the OpenAPI configuration using WithBearerAuth().

Example:

app.GET("/protected", handler).Bearer()

func (*RouteWrapper) Consumes

func (rw *RouteWrapper) Consumes(ct ...string) *RouteWrapper

Consumes sets the content types that this operation accepts in request bodies.

Default: ["application/json"]. Multiple content types can be specified. The first content type is used as the default for request body schemas.

Example:

app.POST("/upload", handler).Consumes("multipart/form-data", "application/json")

func (*RouteWrapper) Deprecated

func (rw *RouteWrapper) Deprecated() *RouteWrapper

Deprecated marks the operation as deprecated.

Deprecated operations are visually distinguished in Swagger UI and should include information in the description about migration paths or alternatives.

Example:

app.GET("/old-endpoint", handler).
    Deprecated().
    Description("Deprecated: Use /new-endpoint instead. Will be removed in v2.0.")

func (*RouteWrapper) Description

func (rw *RouteWrapper) Description(d string) *RouteWrapper

Description sets the operation description.

The description provides detailed information about the operation and supports Markdown formatting. It appears in the expanded operation view.

Example:

app.POST("/users", handler).
    Description("Creates a new user account. Requires admin privileges.")

func (*RouteWrapper) Doc

func (rw *RouteWrapper) Doc(summary, description string) *RouteWrapper

Doc sets both the operation summary and description.

This is a convenience method that sets both fields in a single call. The summary should be a brief one-line description, while the description can be longer and support Markdown formatting.

Example:

app.GET("/users/:id", handler).
    Doc("Get user", "Retrieves a user by their unique identifier. Returns 404 if not found.")
Example

ExampleRouteWrapper_Doc demonstrates documenting a route.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	cfg := openapi.MustNew(
		openapi.WithTitle("My API", "1.0.0"),
	)

	manager := openapi.NewManager(cfg)
	route := manager.Register("POST", "/users")
	route.Doc("Create user", "Creates a new user account").
		Tags("users")

	fmt.Println("Route documented")
}
Output:

Route documented

func (*RouteWrapper) Freeze

func (rw *RouteWrapper) Freeze() *RouteDoc

Freeze freezes the route metadata, making it immutable and thread-safe.

This method:

  • Performs automatic introspection of the request type if set
  • Creates a deep copy of all metadata
  • Marks the wrapper as frozen to prevent further modifications

Freeze is idempotent - calling it multiple times returns the same frozen RouteDoc. This method is automatically called by Manager.GenerateSpec before spec generation.

After freezing, all fluent API methods will have no effect.

Returns the frozen RouteDoc for direct access.

func (*RouteWrapper) GetFrozenDoc

func (rw *RouteWrapper) GetFrozenDoc() *RouteDoc

GetFrozenDoc returns the frozen route documentation.

Returns nil if the route has not been frozen yet. This method is thread-safe and can be called concurrently after RouteWrapper.Freeze.

This is primarily used internally during spec generation.

func (*RouteWrapper) Info

func (rw *RouteWrapper) Info() RouteInfo

Info returns the route information (method and path).

func (*RouteWrapper) OAuth

func (rw *RouteWrapper) OAuth(scheme string, scopes ...string) *RouteWrapper

OAuth adds OAuth authentication requirement with optional scopes.

This is a convenience method that calls Security() with the OAuth scheme name. The security scheme must be defined in the OpenAPI configuration.

Example:

app.GET("/admin", handler).OAuth("oauth2", "admin", "read")

func (*RouteWrapper) OperationID

func (rw *RouteWrapper) OperationID(id string) *RouteWrapper

OperationID sets a custom operation ID for this operation.

Operation IDs are used by code generators and API client libraries. If not set, a semantic operation ID is automatically generated from the HTTP method and path (e.g., "getUserById" for GET /users/:id).

Operation IDs must be unique across all operations. If a duplicate is detected, spec generation will return an error.

Example:

app.GET("/users/:id", handler).OperationID("getUserById")

func (*RouteWrapper) Produces

func (rw *RouteWrapper) Produces(ct ...string) *RouteWrapper

Produces sets the content types that this operation returns in responses.

Default: ["application/json"]. Multiple content types can be specified. The first content type is used as the default for response schemas.

Example:

app.GET("/export", handler).Produces("application/json", "text/csv")

func (*RouteWrapper) Request

func (rw *RouteWrapper) Request(req any, examples ...example.Example) *RouteWrapper

Request sets the request type and optionally provides examples.

The schema is generated from req's type. Examples are handled as follows:

  • No examples provided: req itself is used as the example (if non-zero)
  • Examples provided: they become named examples in OpenAPI

Example (simple):

Request(CreateUserRequest{Name: "John", Email: "john@example.com"})

Example (named examples):

Request(CreateUserRequest{},
	example.New("minimal", CreateUserRequest{Name: "John"}),
	example.New("complete", CreateUserRequest{Name: "John", Email: "john@example.com"}),
)
Example

ExampleRouteWrapper_Request demonstrates documenting request body.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	type CreateUserRequest struct {
		Name  string `json:"name"`
		Email string `json:"email"`
	}

	cfg := openapi.MustNew(
		openapi.WithTitle("My API", "1.0.0"),
	)

	manager := openapi.NewManager(cfg)
	route := manager.Register("POST", "/users")
	route.Doc("Create user", "Creates a new user").
		Request(CreateUserRequest{})

	fmt.Println("Request body documented")
}
Output:

Request body documented

func (*RouteWrapper) Response

func (rw *RouteWrapper) Response(status int, resp any, examples ...example.Example) *RouteWrapper

Response sets the response schema and examples for a status code.

The schema is generated from resp's type. Examples are handled as follows:

  • No examples provided: resp itself is used as the example (if non-zero)
  • Examples provided: they become named examples in OpenAPI

Pass nil for resp for status codes that don't return a body (e.g., 204 No Content).

Example (simple - 99% use case):

Response(200, UserResponse{ID: 123, Name: "John"})

Example (named examples):

Response(200, UserResponse{},
	example.New("success", UserResponse{ID: 123}),
	example.New("admin", UserResponse{ID: 1, Role: "admin"}),
)
Example

ExampleRouteWrapper_Response demonstrates documenting responses.

package main

import (
	"fmt"

	"rivaas.dev/openapi"
)

func main() {
	type User struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	}

	cfg := openapi.MustNew(
		openapi.WithTitle("My API", "1.0.0"),
	)

	manager := openapi.NewManager(cfg)
	route := manager.Register("GET", "/users/:id")
	route.Doc("Get user", "Retrieves a user by ID").
		Response(200, User{}).
		Response(404, map[string]string{"error": "User not found"})

	fmt.Println("Responses documented")
}
Output:

Responses documented

func (*RouteWrapper) ResponseExample

func (rw *RouteWrapper) ResponseExample(status int, ex any) *RouteWrapper

ResponseExample sets an example value for a response status code.

Examples help API consumers understand the expected response format. The example should match the response type set by Response().

Example:

app.GET("/users/:id", handler).
    Response(200, UserResponse{}).
    ResponseExample(200, UserResponse{
        ID:    123,
        Name:  "John Doe",
        Email: "john@example.com",
    })

func (*RouteWrapper) Security

func (rw *RouteWrapper) Security(scheme string, scopes ...string) *RouteWrapper

Security adds a security requirement to the operation.

The scheme name must match a security scheme defined in the OpenAPI configuration. For OAuth schemes, scopes can be specified. Multiple security requirements can be added by calling this method multiple times.

Example:

app.GET("/protected", handler).Security("bearerAuth")
app.GET("/oauth", handler).Security("oauth2", "read", "write")

func (*RouteWrapper) Summary

func (rw *RouteWrapper) Summary(s string) *RouteWrapper

Summary sets the operation summary.

The summary is a brief, one-line description of what the operation does. It appears in the operation list in Swagger UI.

Example:

app.GET("/users", handler).Summary("List all users")

func (*RouteWrapper) Tags

func (rw *RouteWrapper) Tags(tags ...string) *RouteWrapper

Tags adds tags to the operation for grouping in Swagger UI.

Tags help organize operations into logical groups. Operations with the same tag appear together in Swagger UI. Multiple tags can be added by calling this method multiple times or passing multiple arguments.

Example:

app.GET("/users", handler).Tags("users", "management")
app.POST("/users", handler).Tags("users")

type Schema

type Schema struct {
	// Type is the JSON Schema type: "string", "number", "integer", "boolean", "array", "object".
	Type string `json:"type,omitempty"`

	// Format provides additional type information (e.g., "date-time", "email", "int64").
	Format string `json:"format,omitempty"`

	// Description provides documentation for the schema.
	Description string `json:"description,omitempty"`

	// Properties defines object properties (for type "object").
	Properties map[string]*Schema `json:"properties,omitempty"`

	// Required lists required property names (for type "object").
	Required []string `json:"required,omitempty"`

	// Items defines the item schema (for type "array").
	Items *Schema `json:"items,omitempty"`

	// AdditionalProperties defines the schema for additional properties (for type "object").
	AdditionalProperties *Schema `json:"additionalProperties,omitempty"`

	// Ref is a reference to a component schema (e.g., "#/components/schemas/User").
	Ref string `json:"$ref,omitempty"`

	// Enum lists allowed values for the schema.
	Enum []any `json:"enum,omitempty"`

	// Default is the default value for the schema.
	Default any `json:"default,omitempty"`

	// Example provides an example value for the schema.
	Example any `json:"example,omitempty"`

	// Nullable indicates if the value can be null.
	Nullable bool `json:"nullable,omitempty"`

	// Minimum is the minimum numeric value (for type "number" or "integer").
	Minimum *float64 `json:"minimum,omitempty"`

	// Maximum is the maximum numeric value (for type "number" or "integer").
	Maximum *float64 `json:"maximum,omitempty"`

	// MinLength is the minimum string length (for type "string").
	MinLength *int `json:"minLength,omitempty"`

	// MaxLength is the maximum string length (for type "string").
	MaxLength *int `json:"maxLength,omitempty"`

	// Pattern is a regex pattern for string validation (for type "string").
	Pattern string `json:"pattern,omitempty"`
}

Schema represents a JSON Schema for describing data structures.

Schemas are used to define parameter types, request bodies, and response bodies. They support the full JSON Schema specification compatible with OpenAPI 3.0.4.

type SecurityReq

type SecurityReq struct {
	Scheme string
	Scopes []string
}

SecurityReq represents a security requirement for an operation.

It specifies which security scheme is required and, for OAuth schemes, which scopes are needed.

type SecurityRequirement

type SecurityRequirement map[string][]string

SecurityRequirement lists the required security schemes for an operation.

The map key is the security scheme name, and the value is a list of required scopes (empty list for schemes that don't use scopes, like Bearer or API Key).

type SecurityScheme

type SecurityScheme struct {
	// Type is the security scheme type: "http", "apiKey", "oauth2", "openIdConnect", "mutualTLS" (3.1+).
	Type string `json:"type"`

	// Description provides documentation for the security scheme.
	Description string `json:"description,omitempty"`

	// Name is the parameter name (for type "apiKey").
	Name string `json:"name,omitempty"`

	// In is the parameter location: "header", "query", or "cookie" (for type "apiKey").
	In string `json:"in,omitempty"`

	// Scheme is the HTTP scheme (for type "http", e.g., "bearer").
	Scheme string `json:"scheme,omitempty"`

	// BearerFormat is the bearer token format (for type "http" with scheme "bearer", e.g., "JWT").
	BearerFormat string `json:"bearerFormat,omitempty"`

	// Flows contains OAuth2 flow configuration (for type "oauth2").
	Flows *OAuthFlows `json:"flows,omitempty"`

	// OpenIDConnectURL is the well-known URL to discover OpenID Connect provider metadata (for type "openIdConnect").
	OpenIDConnectURL string `json:"openIdConnectUrl,omitempty"`
}

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

Security schemes define authentication/authorization methods like Bearer tokens, API keys, OAuth flows, OpenID Connect, or mutual TLS.

type Server

type Server struct {
	// URL is the server URL (required, e.g., "https://api.example.com").
	// Supports variable substitution with {variableName} syntax.
	URL string `json:"url"`

	// Description helps distinguish between different server environments.
	Description string `json:"description,omitempty"`

	// Variables defines variable substitutions for the server URL template.
	Variables map[string]*ServerVariable `json:"variables,omitempty"`

	// Extensions contains specification extensions (fields prefixed with x-).
	//
	// Direct mutation of this map after New/MustNew bypasses Config.Validate().
	// However, projection-time filtering via copyExtensions still applies:
	// - Keys must start with "x-"
	// - In OpenAPI 3.1.x, keys starting with "x-oai-" or "x-oas-" are reserved and will be filtered
	//
	// Prefer using helper options (e.g., WithServerExtension) instead of direct mutation.
	Extensions map[string]any `json:"-"`
}

Server represents a server URL and optional description.

type ServerVariable

type ServerVariable struct {
	// Enum is an enumeration of allowed values (optional).
	// In OpenAPI 3.1, this array MUST NOT be empty if present.
	Enum []string `json:"enum,omitempty"`

	// Default is the default value for substitution (required).
	// If enum is defined, this value MUST exist in the enum (3.1) or SHOULD exist (3.0).
	Default string `json:"default"`

	// Description provides additional information about the variable.
	Description string `json:"description,omitempty"`

	// Extensions contains specification extensions (fields prefixed with x-).
	Extensions map[string]any `json:"-"`
}

ServerVariable represents a variable for server URL template substitution.

type Spec

type Spec struct {
	// OpenAPI version string (e.g., Version30 or Version31).
	OpenAPI string `json:"openapi"`

	// Info contains API metadata (title, version, description, contact, license).
	Info Info `json:"info"`

	// Servers lists available server URLs for the API.
	Servers []Server `json:"servers,omitempty"`

	// Paths maps path patterns to PathItem objects containing operations.
	Paths map[string]*PathItem `json:"paths"`

	// Components holds reusable schemas, security schemes, etc.
	Components *Components `json:"components,omitempty"`

	// Tags provides additional metadata for operations.
	Tags []Tag `json:"tags,omitempty"`

	// Security defines global security requirements applied to all operations.
	Security []SecurityRequirement `json:"security,omitempty"`

	// ExternalDocs provides external documentation links.
	ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"`
}

Spec represents the root OpenAPI 3.0.4 document.

This is the top-level structure that represents a complete OpenAPI specification. It can be marshaled to JSON and served to API documentation tools and code generators.

type SyntaxHighlightConfig

type SyntaxHighlightConfig struct {
	// Activated enables or disables syntax highlighting.
	Activated bool

	// Theme specifies the color scheme for syntax highlighting.
	Theme SyntaxTheme
}

SyntaxHighlightConfig controls syntax highlighting appearance in Swagger UI.

type SyntaxTheme

type SyntaxTheme string

SyntaxTheme defines the syntax highlighting theme used for code examples in Swagger UI.

Different themes provide different color schemes for code snippets and examples.

const (
	// SyntaxThemeAgate provides a dark theme with blue accents.
	SyntaxThemeAgate SyntaxTheme = "agate"

	// SyntaxThemeArta provides a dark theme with orange accents.
	SyntaxThemeArta SyntaxTheme = "arta"

	// SyntaxThemeMonokai provides a dark theme with vibrant colors.
	SyntaxThemeMonokai SyntaxTheme = "monokai"

	// SyntaxThemeNord provides a dark theme with cool blue tones.
	SyntaxThemeNord SyntaxTheme = "nord"

	// SyntaxThemeObsidian provides a dark theme with green accents.
	SyntaxThemeObsidian SyntaxTheme = "obsidian"

	// SyntaxThemeTomorrowNight provides a dark theme with muted colors.
	SyntaxThemeTomorrowNight SyntaxTheme = "tomorrow-night"

	// SyntaxThemeIdea provides a light theme similar to IntelliJ IDEA.
	SyntaxThemeIdea SyntaxTheme = "idea"
)

Syntax highlighting theme constants.

type Tag

type Tag struct {
	// Name is the tag name (required).
	Name string `json:"name"`

	// Description provides documentation for the tag.
	Description string `json:"description,omitempty"`

	// ExternalDocs provides additional external documentation for this tag.
	ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"`

	// Extensions contains specification extensions (fields prefixed with x-).
	//
	// Direct mutation of this map after New/MustNew bypasses Config.Validate().
	// However, projection-time filtering via copyExtensions still applies:
	// - Keys must start with "x-"
	// - In OpenAPI 3.1.x, keys starting with "x-oai-" or "x-oas-" are reserved and will be filtered
	//
	// Prefer using helper options (e.g., WithTagExtension) instead of direct mutation.
	Extensions map[string]any `json:"-"`
}

Tag adds metadata to a single tag that is used by the Operation Object.

Tags help organize operations in Swagger UI by grouping related endpoints.

type TagsSorterMode

type TagsSorterMode string

TagsSorterMode controls how tags are sorted in Swagger UI.

Tags can be sorted alphabetically or left in server order.

const (
	// TagsSorterAlpha sorts tags alphabetically.
	TagsSorterAlpha TagsSorterMode = "alpha"

	// TagsSorterNone uses server order without sorting.
	TagsSorterNone TagsSorterMode = ""
)

TagsSorter constants control tag sorting.

Directories

Path Synopsis
Package example provides types and constructors for OpenAPI Example Objects.
Package example provides types and constructors for OpenAPI Example Objects.
Package export provides OpenAPI specification export functionality.
Package export provides OpenAPI specification export functionality.
internal
build
Package build provides OpenAPI specification building from route metadata.
Package build provides OpenAPI specification building from route metadata.
schema
Package schema provides schema generation from Go types using reflection.
Package schema provides schema generation from Go types using reflection.
Package model provides version-agnostic intermediate representation (IR) types for OpenAPI specifications.
Package model provides version-agnostic intermediate representation (IR) types for OpenAPI specifications.
Package validate provides OpenAPI specification validation functionality.
Package validate provides OpenAPI specification validation functionality.

Jump to

Keyboard shortcuts

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