OPEN SWAG GO
API Reference

Core Package

The root openswag package contains every type you need to define an OpenAPI spec and serve interactive documentation from your Go application.

Config

Top-level configuration passed to openswag.New().

type Config struct {
    Info     Info       // API metadata (title, version, description)
    Servers  []Server   // Server URLs shown in the docs UI
    Tags     []Tag      // Logical groupings for endpoints
    UI       UIConfig   // Scalar UI appearance settings
    Auth     AuthConfig // Security schemes exposed under components.securitySchemes
    DocsAuth *DocsAuth  // Optional password/API-key protection for the docs page
    InlineSchemas bool  // Inline every struct instead of emitting components.schemas (v1.3.0+)
}

The mount path (e.g. /docs) is passed to docs.Mount(mux, "/docs"), not configured on Config.

Fields

FieldTypeDescription
InfoInfoAPI title, version, description, contact, and license
Servers[]ServerBase URLs displayed in the server dropdown
Tags[]TagGrouping tags that organise endpoints in the sidebar
UIUIConfigTheme, layout, and Scalar UI options
AuthAuthConfigSecurity schemes exposed under components.securitySchemes
DocsAuth*DocsAuthProtect the docs page with basic auth or an API key
InlineSchemasboolDefault false: every named struct used in a request or response body is emitted once under components.schemas and referenced with $ref. true restores the pre-v1.3.0 output: every struct inlined at each use and recursive back-edges cut off with {type: object, description: "Recursive reference to ..."}. See Schema Components (v1.3.0+)

Docs

Docs is the main handle returned by openswag.New(). It holds the compiled spec and serves the UI.

func New(cfg Config) *Docs
type Docs struct {
    // unexported fields
}
 
func (d *Docs) Add(endpoint Endpoint)                       // Register one endpoint
func (d *Docs) AddAll(endpoints ...Endpoint)                // Register multiple endpoints
func (d *Docs) Validate() error                             // Report invalid endpoint definitions (v1.3.0+)
func (d *Docs) Mount(mux *http.ServeMux, basePath string)   // Serve UI + spec on a ServeMux
func (d *Docs) Handler() http.HandlerFunc                   // Handler that serves the docs UI
func (d *Docs) SpecHandler() http.HandlerFunc               // Handler that serves the raw OpenAPI JSON
func (d *Docs) SpecJSON() ([]byte, error)                   // The OpenAPI spec as JSON bytes
func (d *Docs) BuildSpec() *spec.OpenAPI                    // The compiled spec object
func (d *Docs) GetUIConfig() (string, error)                // Serialized UI config (advanced)

Add and AddAll never fail: BuildSpec keeps the last of two endpoints with the same method and path and skips unsupported methods. Validate (v1.3.0+) returns one joined error (errors.Join) listing every duplicate method+path pair (compared after upper-casing the method and normalising /users/:id to /users/{id}), every method other than GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS and TRACE, and every duplicate operationId. It returns nil when everything is valid. Call it once after AddAll and treat an error as fatal.

Usage

docs := openswag.New(cfg)
docs.AddAll(endpoints...)
if err := docs.Validate(); err != nil {
    log.Fatal(err)
}
 
// Serve with net/http
mux := http.NewServeMux()
docs.Mount(mux, "/docs")
http.ListenAndServe(":8080", mux)

Endpoint

Describes a single API operation.

type Endpoint struct {
    Method      string            // GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE
    Path        string            // "/users/{id}"; "/users/:id", "/files/*path" are normalised
    OperationID string            // Overrides the generated operationId (v1.3.0+)
    Summary     string            // Short one-line description
    Description string            // Detailed explanation (Markdown supported)
    Tags        []string          // Grouping tags for the sidebar
    Parameters  []Parameter       // Path, query, and header parameters (manual)
    QueryParams interface{}       // Struct whose fields become query params (form/description/example tags)
    PathParams  interface{}       // Struct whose fields become path params (param tag)
    RequestBody *RequestBody      // Request body (nil for GET/DELETE)
    Responses   Responses         // map[int]ResponseSpec keyed by HTTP status
    Security    []string          // Security scheme names applied to this endpoint
    Deprecated  bool              // Mark the endpoint as deprecated
}
 
// Responses is a convenience alias used in endpoint literals.
type Responses = map[int]ResponseSpec

Fields

FieldTypeDescription
MethodstringHTTP verb — GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE (case-insensitive; HEAD/OPTIONS/TRACE v1.3.0+)
PathstringRoute path with {param} placeholders. Router-style :id, *path and chi {id:[0-9]+} segments are normalised to {name} (v1.3.0+)
OperationIDstringOverrides the generated operationId (v1.3.0+). When empty, it is derived from method + path in lowerCamelCase: GET /users/{id} → getUsersById, GET / → getRoot
SummarystringOne-line summary shown in the sidebar
DescriptionstringLonger description, supports Markdown
Tags[]stringGroups the endpoint under one or more sidebar sections
Parameters[]ParameterManually declared path, query, and header parameters
QueryParamsinterface{}A struct whose fields (with form tags) become query parameters
PathParamsinterface{}A struct whose fields (with param tags) become path parameters
RequestBody*RequestBodyPayload definition for write operations — build with Body() / BodyWithDesc() / FormBody()
ResponsesResponsesStatus-code map — build entries with Response(desc, schema)
Security[]stringNames of security schemes this endpoint requires
DeprecatedboolFlags the endpoint as deprecated in the spec

Parameter

Describes a single path, query, or header parameter.

type Parameter struct {
    Name        string       // Parameter name, e.g. "id"
    In          string       // Location: "path", "query", "header", or "cookie"
    Description string       // Human-readable description
    Required    bool         // Whether the parameter is mandatory
    Schema      *spec.Schema // Parameter schema (e.g. spec.NewSchema("string"))
    Example     interface{}  // Optional example value
}

RequestBody

Describes the payload for POST, PUT, and PATCH operations.

type RequestBody struct {
    Description string      // What the body represents
    ContentType string      // MIME type, e.g. "application/json", "multipart/form-data"
    Required    bool        // Whether the body is mandatory
    Schema      interface{} // Go struct for schema generation
}

ContentType is honored end-to-end — set it to multipart/form-data for file uploads and the generated spec will list that media type instead of application/json. Prefer the Body() / FormBody() / FormURLEncodedBody() helpers above when you don't need custom fields.

Request body schemas only carry examples where you set an example:"..." tag on a field (the auto-generated body example from v1.1.0 was removed in v1.1.1). Example values are type-coerced (e.g. example:"42" on an int64 field produces the integer 42, not the string "42"). A top-level pointer passed as Schema (e.g. &CreateUserRequest{}) produces the same, non-nullable schema as the value.

ResponseSpec & Response()

ResponseSpec is the struct stored in Endpoint.Responses. Build entries with the Response() helper for the concise, decorator-style form documented in the README:

type ResponseSpec struct {
    Description string      // What this response means
    Schema      interface{} // Go struct for schema generation (optional)
}
 
// Response builds a ResponseSpec. Pass the schema as the second argument,
// or omit it for empty responses (e.g. 204 No Content).
func Response(description string, schema ...interface{}) ResponseSpec

Responses are keyed by status code in the Endpoint.Responses map:

Responses: openswag.Responses{
    200: openswag.Response("A list of pets", []Pet{}),
    204: openswag.Response("Deleted"),
    404: openswag.Response("Not found", ErrorResponse{}),
},

The struct used to be named Response. v1.2.0 renamed it to ResponseSpec so that openswag.Response(...) could become a constructor function. Field literals still work — just replace the type name.

Request body helpers

*RequestBody literals are verbose. Use these constructors:

// JSON body (Required: true, ContentType: "application/json")
openswag.Body(CreateUserRequest{})
 
// JSON body with a description
openswag.BodyWithDesc("Pet object to create", Pet{})
 
// multipart/form-data — for file uploads / HTML forms
openswag.FormBody(UploadRequest{})
 
// application/x-www-form-urlencoded
openswag.FormURLEncodedBody(LoginForm{})

All four return *RequestBody, so they slot directly into Endpoint.RequestBody.

Parameter helpers

Decorator-style helpers that return a Parameter ready to drop into Endpoint.Parameters:

openswag.PathParam("id", "User ID")                          // required path string
openswag.QueryParam("include", "Related resources")           // optional query string
openswag.RequiredQueryParam("filter", "Required filter")      // required query string
openswag.HeaderParam("X-Request-ID", "Request tracking ID")   // optional header
openswag.CookieParam("session", "Session cookie")             // optional cookie

All produce a string-typed schema. For typed query/path params, prefer the struct-based QueryParams / PathParams form below.

AuthConfig

Top-level container for the security schemes your spec advertises.

type AuthConfig struct {
    PersistCredentials bool         // No runtime effect: not passed to the docs UI (see below)
    Schemes            []AuthScheme // Schemes exposed under components.securitySchemes
}
 
type AuthScheme struct {
    Name         string // ID referenced from Endpoint.Security
    Type         string // "http", "apiKey", "oauth2", "openIdConnect"
    Scheme       string // "bearer" / "basic" when Type == "http"
    BearerFormat string // Hint for http+bearer (e.g. "JWT")
    In           string // "header" / "query" / "cookie" when Type == "apiKey"
    ParamName    string // Header/query/cookie name carrying the credential
    Description  string
}

PersistCredentials exists on the struct but is not read anywhere: it is not part of the spec and is not passed to Scalar, so setting it has no effect. Credentials entered in the docs UI are handled client-side by Scalar.

Build entries with the helpers:

Auth: openswag.AuthConfig{
    Schemes: []openswag.AuthScheme{
        openswag.BearerAuth(openswag.SecurityBearerAuth),
        openswag.APIKeyAuth("apiKey", "X-API-Key"),
        openswag.BasicAuth(openswag.SecurityBasicAuth),
        openswag.CookieAuth(openswag.SecurityCookieAuth, "session_id"),
    },
},

Custom scheme names referenced from Endpoint.Security that are not one of the Security* predefined constants and not registered in AuthConfig.Schemes are intentionally left out of the spec — prior versions silently materialised them as http-bearer, which masked typos. Register the scheme explicitly to keep the previous behavior.

Predefined security names

Use these constants in Endpoint.Security to pick up the built-in spec entries without supplying an AuthScheme:

ConstantResolves to
SecurityBearerAuthhttp + bearer + JWT
SecurityBasicAuthhttp + basic
SecurityApiKeyapiKey in X-API-Key header
SecurityApiKeyQueryapiKey in ?api_key= query
SecurityCookieAuthapiKey in session_id cookie
SecurityOAuth2oauth2 authorization code

UIConfig

Controls the Scalar-based documentation UI appearance.

type UIConfig struct {
    Theme              string // Scalar theme name, passed to Scalar as-is (default "purple")
    DarkMode           bool   // Enable dark mode by default
    Layout             string // Scalar layout, passed as-is (default "modern")
    ShowSidebar        bool   // Show the navigation sidebar
    SidebarSearch      bool   // Deprecated: has no effect (v1.3.0+)
    TagGrouping        bool   // Deprecated: has no effect (v1.3.0+)
    CollapsibleSchemas bool   // Deprecated: has no effect (v1.3.0+)
    CustomCSS          string // Raw CSS injected verbatim into the docs page (trusted input only)
    ScalarVersion      string // Pin @scalar/api-reference; "" = ui.DefaultScalarVersion ("1.75.0") (v1.3.0+)
    SpecCORSOrigin     string // Access-Control-Allow-Origin on the spec: "" = "*", "-" = omitted (v1.3.0+)
}
FieldDescription
ThemePassed through unchanged as Scalar's theme option; any theme name supported by the loaded Scalar version works. Defaults to "purple". See Theming.
SidebarSearch, TagGrouping, CollapsibleSchemasDeprecated: has no effect (v1.3.0+). They were never passed to Scalar, which always shows the sidebar search, groups operations by tag and renders collapsible model sections. Kept so existing configuration compiles.
ScalarVersionVersion of @scalar/api-reference loaded from the CDN (v1.3.0+). Empty uses ui.DefaultScalarVersion ("1.75.0"), so upstream Scalar releases no longer change your docs UI without you opting in.
SpecCORSOriginControls the Access-Control-Allow-Origin header sent by SpecHandler (v1.3.0+). "" keeps the historical *, "-" omits the header, any other value (e.g. "https://app.example.com") is sent as-is.
CustomCSSInserted verbatim into a <style> element. It must come from trusted configuration. The page title and spec URL, by contrast, are escaped (the page is rendered with html/template since v1.3.0).

DocsAuth

Protects the documentation page with credentials.

type DocsAuth struct {
    Enabled  bool   // Turn protection on
    Username string // Basic auth username
    Password string // Basic auth password
    Realm    string // Basic auth realm (optional)
    APIKey   string // Alternative: protect with an API key (?key=...)
}

When both APIKey and Username/Password are set, either one grants access: the ?key= API key is checked first, then the basic auth credentials. A request that matches neither gets 401 Unauthorized with a WWW-Authenticate challenge.

If Enabled is true but neither APIKey nor both Username and Password are set, every request gets 500 DocsAuth enabled but no credentials configured (v1.3.0+; earlier versions answered 401, which looked like a wrong password).

Info

API metadata rendered in the docs header.

type Info struct {
    Title          string   // API title
    Version        string   // Semantic version, e.g. "1.0.0"
    Description    string   // Markdown description
    TermsOfService string   // URL to terms of service
    Contact        *Contact // Maintainer contact info
    License        *License // License details
}

Server

A base URL entry shown in the server dropdown.

type Server struct {
    URL         string // Base URL, e.g. "https://api.example.com"
    Description string // Label for this server
}

Tag

A logical grouping for endpoints.

type Tag struct {
    Name        string // Tag name referenced by Endpoint.Tags
    Description string // Displayed in the sidebar
}

Contact

Maintainer contact information embedded in Info.

type Contact struct {
    Name  string // Contact name
    URL   string // Contact URL
    Email string // Contact email
}

License

License details embedded in Info.

type License struct {
    Name string // License name, e.g. "MIT"
    URL  string // URL to the full license text
}

Parameters from structs

Instead of declaring Parameters by hand, set Endpoint.QueryParams or Endpoint.PathParams to a struct value. Query-param names come from the query tag, then form; path-param names from the path tag, then param; json and the lower-cased field name are fallbacks. The description and example tags annotate each parameter (doc is a fallback for description).

Since v1.3.0 parameter fields follow the same tag rules as request bodies: swagger:"required" or a validator required rule marks a query parameter required, and format, enum and validator constraints (validate:"min=1,max=100", oneof=...) are applied to the parameter schema. A pointer field means optional, not nullable. Path parameters are always required.

type ListProductsQuery struct {
    Page     int    `form:"page" description:"Page number" example:"1"`
    PerPage  int    `form:"per_page" description:"Items per page" example:"20"`
    Category string `form:"category" description:"Filter by category ID"`
}
 
type ProductPathParams struct {
    ID string `param:"id" description:"Product ID" example:"prod_123"`
}
 
openswag.Endpoint{
    Method:      "GET",
    Path:        "/products/{id}",
    PathParams:  ProductPathParams{},
    QueryParams: ListProductsQuery{},
    // ...
}

For full control you can still declare Parameters manually with spec.NewSchema:

import "github.com/gopackx/open-swag-go/pkg/spec"
 
Parameters: []openswag.Parameter{
    {Name: "id", In: "path", Description: "User ID", Required: true, Schema: spec.NewSchema("string")},
},

Quick Example

package main
 
import (
    "log"
    "net/http"
    openswag "github.com/gopackx/open-swag-go"
)
 
func main() {
    cfg := openswag.Config{
        Info: openswag.Info{
            Title:   "Pet Store",
            Version: "1.0.0",
        },
        Servers: []openswag.Server{
            {URL: "http://localhost:8080", Description: "Local"},
        },
    }
 
    endpoints := []openswag.Endpoint{
        {
            Method:  "GET",
            Path:    "/pets",
            Summary: "List all pets",
            Tags:    []string{"Pets"},
            Responses: openswag.Responses{
                200: openswag.Response("A list of pets"),
            },
        },
    }
 
    docs := openswag.New(cfg)
 
    docs.AddAll(endpoints...)
    if err := docs.Validate(); err != nil {
        log.Fatal(err)
    }
    http.Handle("/docs/", docs.Handler())
    http.ListenAndServe(":8080", nil)
}