Help us shape the future of Go! Take the 2026 Go Developer Survey

openapi

package
v0.30.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 20 Imported by: 1

Documentation

Overview

Package openapi generates an OpenAPI 3.1 document from the router: typed routes (api.Register) are described from their input and output types and `validate` tags; plain routes get a generic entry.

doc := openapi.Generate(r.Routes(), openapi.Info{Title: "Shop", Version: "1.0.0"})

See https://github.com/AlexGalhardo/vukem/blob/main/docs/api.md.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrDuplicateOperationID = errors.New("openapi: duplicate operationId")

ErrDuplicateOperationID is returned by Build when two routes in the document share an operationId: the route's own name, so groups that reuse a local name (api.v1.index and api.v2.index) collide, and the generated clients would get clashing methods.

View Source
var ErrEmptyDocument = errors.New("openapi: path prefix matches no route")

ErrEmptyDocument is returned by Build when Info.PathPrefix is set and filters out every route: the resulting document has no paths, which looks exactly like a broken app, and the usual cause is a mistyped or shell-rewritten prefix. A router with no documentable route at all is still an empty document and no error.

View Source
var ErrNoOperation = errors.New("openapi: no operation matches the request")

ErrNoOperation is returned when the document has no operation for the request.

View Source
var ErrUnknownSecurityScheme = errors.New("openapi: unknown security scheme")

ErrUnknownSecurityScheme is returned by Build when an operation lists a security scheme (api.Op.Security) that is neither predefined ("bearer") nor declared in Info.SecuritySchemes.

Functions

func GoClient added in v0.19.0

func GoClient(d *Document, pkg string) ([]byte, error)

GoClient returns gofmt'd Go source for a stdlib-only client in package pkg: one type per component schema, <Operation>Body, <Operation>Query and <Operation>Response for inline schemas, and a Client with one method per operation with an operationId. Path parameters are typed arguments; any non-2xx response becomes an *Error carrying the RFC 9457 problem.

Mapping: objects are structs (optional fields get omitempty, optional or nullable scalars and structs are pointers), additionalProperties maps, string enums named string types with constants, date-time strings time.Time, integers int64, numbers float64, and unions json.RawMessage.

func TypeScript

func TypeScript(d *Document, zod bool) (string, error)

TypeScript returns TypeScript declarations for the document: one type per component schema, plus <Operation>Body, <Operation>Query and <Operation>Response for every operation with an operationId. With zod set, Zod 4 schemas follow the types: <Name>Schema for every component and <Operation>BodySchema for every JSON request body.

func TypeScriptClient added in v0.19.0

func TypeScriptClient(d *Document) (string, error)

TypeScriptClient returns a dependency-free TypeScript client for the document: the TypeScript types (without Zod), <Operation>Params for path parameters, ApiError and createClient, which has one async method per operation with an operationId (camelCase: "products.store" becomes productsStore). It needs fetch, URLSearchParams and Headers, so it runs in browsers and Node 18+.

Types

type Components

type Components struct {
	Schemas         map[string]Schema   `json:"schemas,omitempty"`
	Responses       map[string]Response `json:"responses,omitempty"`
	SecuritySchemes map[string]Schema   `json:"securitySchemes,omitempty"`
}

Components holds reusable schemas, responses and security schemes.

type Document

type Document struct {
	OpenAPI    string                           `json:"openapi"`
	Info       docInfo                          `json:"info"`
	Servers    []server                         `json:"servers,omitempty"`
	Paths      map[string]map[string]*Operation `json:"paths"`
	Components Components                       `json:"components"`
}

Document is an OpenAPI 3.1 document.

func Build added in v0.28.0

func Build(routes []router.RouteInfo, info Info) (*Document, error)

Build is Generate returning its error. The operationId of every route is its own name, without group name prefixes (Op.Name for a typed route), typed or not. A plain POST, PUT or PATCH route documents an optional JSON body of any shape, and plain routes document a default response of any content, so generated clients can send a body and ValidateResponse accepts what they return.

func Generate

func Generate(routes []router.RouteInfo, info Info) *Document

Generate builds the document for routes (router.Routes()). It panics on the errors Build returns (duplicate operationIds, an undeclared security scheme, a path prefix matching no route): they are programming errors that should surface at boot or in a test.

Example
package main

import (
	"fmt"

	"github.com/AlexGalhardo/vukem/api"
	"github.com/AlexGalhardo/vukem/openapi"
	"github.com/AlexGalhardo/vukem/router"
	"github.com/AlexGalhardo/vukem/web"
)

type exShowProduct struct {
	ID int `json:"id"`
}

type exProduct struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

func main() {
	r := router.New(nil)
	api.Register(r, "GET /api/products/{id}", api.Op{Name: "products.show", Summary: "Show a product"},
		func(_ *web.Ctx, in exShowProduct) (exProduct, error) {
			return exProduct{ID: in.ID}, nil
		})

	doc := openapi.Generate(r.Routes(), openapi.Info{Title: "Shop", Version: "1.0.0"})
	op := doc.Paths["/api/products/{id}"]["get"]
	fmt.Println(doc.OpenAPI, op.OperationID, op.Summary)
}
Output:
3.1.0 products.show Show a product

func (*Document) ValidateResponse

func (d *Document) ValidateResponse(method, path string, status int, body []byte) error

ValidateResponse checks a response body against the document: the operation for method and path (a concrete URL path), then the schema declared for status, or the "default" response. It supports the JSON Schema subset Generate emits.

type Example added in v0.29.0

type Example struct {
	Summary     string `json:"summary,omitempty"`
	Description string `json:"description,omitempty"`
	Value       any    `json:"value,omitempty"`
}

Example is one named example value (an OpenAPI Example Object).

type Field

type Field struct {
	Key      string
	Type     reflect.Type
	Rules    []string
	Required bool
	Doc      string
	// Example is the raw `example` struct tag; ExampleValue decodes it.
	Example string
}

Field is one JSON property of a struct.

func Fields

func Fields(t reflect.Type) []Field

Fields lists the JSON properties of struct t (embedded structs are flattened, `json:"-"` is skipped), with their validate rules, their `doc` description and their raw `example` tag.

func (Field) ExampleValue added in v0.29.0

func (f Field) ExampleValue() any

ExampleValue decodes the field's `example` tag into a value of the field's JSON type, so the document shows 7 rather than "7". A composite field (slice, map, struct) takes JSON; anything that does not decode stays the raw string. It returns nil when there is no tag.

type Info

type Info struct {
	Title       string
	Version     string
	Description string
	Servers     []string
	// PathPrefix keeps only routes under it, matching whole segments
	// ("/api/v1" keeps /api/v1 and /api/v1/..., not /api/v10); empty keeps
	// all.
	PathPrefix string
	// SecuritySchemes adds or replaces schemes; "bearer" (HTTP bearer
	// token) is predefined.
	SecuritySchemes map[string]Schema
}

Info configures the document.

type MediaType

type MediaType struct {
	Schema Schema `json:"schema"`
	// Example is a single example value for this content type.
	Example any `json:"example,omitempty"`
	// Examples are named alternatives, so two responses that share one
	// component schema can still show different payloads; OpenAPI ignores
	// Example when it is set.
	Examples map[string]Example `json:"examples,omitempty"`
}

MediaType wraps a schema for one content type.

type Operation

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

Operation is one method on a path.

type Parameter

type Parameter struct {
	Name        string `json:"name"`
	In          string `json:"in"`
	Required    bool   `json:"required,omitempty"`
	Description string `json:"description,omitempty"`
	Schema      Schema `json:"schema"`
	// Example is a single example value, from the field's `example` tag
	// when the generator built this parameter.
	Example any `json:"example,omitempty"`
	// Examples are named alternatives; OpenAPI ignores Example when it is
	// set.
	Examples map[string]Example `json:"examples,omitempty"`
}

Parameter is a path or query parameter.

type RequestBody

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

RequestBody is an operation's body.

type Response

type Response struct {
	Ref         string               `json:"$ref,omitempty"`
	Description string               `json:"description,omitempty"`
	Content     map[string]MediaType `json:"content,omitempty"`
}

Response is a response or a $ref to a shared one.

type Schema

type Schema = map[string]any

Schema is a JSON Schema (2020-12, as used by OpenAPI 3.1) object.

type Schemas

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

Schemas turns Go types into JSON Schemas, collecting named structs as reusable components. Constraints come from the same `validate` tags the z package enforces, so the document matches what the server accepts.

func NewSchemas

func NewSchemas() *Schemas

NewSchemas returns an empty component registry.

func (*Schemas) Components

func (s *Schemas) Components() map[string]Schema

Components returns the named schemas collected so far.

func (*Schemas) For

func (s *Schemas) For(t reflect.Type) Schema

For returns the schema of t: a $ref for named structs, inline otherwise.

func (*Schemas) Object

func (s *Schemas) Object(t reflect.Type, skip map[string]bool) Schema

Object returns the inline object schema of struct t without the properties named in skip (e.g. path parameters).

type Skip

type Skip struct{}

Skip hides a route from the document: r.Get(...).Doc(openapi.Skip{}).

Jump to

Keyboard shortcuts

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