muxopenapi

package module
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: May 12, 2026 License: MIT Imports: 7 Imported by: 0

README ยถ

muxopenapi

Go Reference Go Report Card

A lightweight adapter for the gorilla/mux package that automatically generates OpenAPI 3.x specifications from your routes using oaswrap/spec.

Features

  • โšก Seamless Integration โ€” Works with your existing gorilla/mux routes and handlers
  • ๐Ÿ“ Automatic Documentation โ€” Generate OpenAPI specs from route definitions and struct tags
  • ๐ŸŽฏ Type Safety โ€” Full Go type safety for OpenAPI configuration
  • ๐Ÿ”ง Multiple UI Options โ€” Swagger UI, Stoplight Elements, ReDoc, Scalar or RapiDoc served automatically at /docs
  • ๐Ÿ“„ YAML Export โ€” OpenAPI spec available at /docs/openapi.yaml
  • ๐Ÿš€ Low Overhead โ€” Minimal runtime work beyond route registration and docs serving

Installation

go get github.com/oaswrap/spec/adapter/muxopenapi

Quick Start

package main

import (
	"encoding/json"
	"log"
	"net/http"
	"time"

	"github.com/gorilla/mux"
	"github.com/oaswrap/spec/adapter/muxopenapi"
	"github.com/oaswrap/spec/option"
)

func main() {
	mux := mux.NewRouter()
	r := muxopenapi.NewRouter(mux,
		option.WithTitle("My API"),
		option.WithVersion("1.0.0"),
		option.WithSecurity("bearerAuth", option.SecurityHTTPBearer("Bearer")),
	)

	api := r.PathPrefix("/api").Subrouter()
	v1 := api.PathPrefix("/v1").Subrouter()

	v1.HandleFunc("/login", LoginHandler).Methods("POST").With(
		option.Summary("User Login"),
		option.Request(new(LoginRequest)),
		option.Response(200, new(LoginResponse)),
	)
	auth := v1.PathPrefix("/").Subrouter().With(
		option.GroupSecurity("bearerAuth"),
	)
	auth.Use(AuthMiddleware)
	auth.HandleFunc("/users/{id}", GetUserHandler).Methods("GET").With(
		option.Summary("Get User by ID"),
		option.Request(new(GetUserRequest)),
		option.Response(200, new(User)),
	)

	log.Printf("๐Ÿš€ OpenAPI docs available at: %s", "http://localhost:3000/docs")

	// Start the server
	server := &http.Server{
		Handler:           mux,
		Addr:              ":3000",
		ReadHeaderTimeout: 5 * time.Second,
	}
	if err := server.ListenAndServe(); err != nil {
		log.Fatal(err)
	}
}

type LoginRequest struct {
	Username string `json:"username" required:"true"`
	Password string `json:"password" required:"true"`
}

type LoginResponse struct {
	Token string `json:"token"`
}

type GetUserRequest struct {
	ID string `path:"id" required:"true"`
}

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

func AuthMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Simulate authentication logic
		authHeader := r.Header.Get("Authorization")
		if authHeader != "" && authHeader == "Bearer example-token" {
			next.ServeHTTP(w, r)
		} else {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
		}
	})
}

func LoginHandler(w http.ResponseWriter, r *http.Request) {
	var req LoginRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid request", http.StatusBadRequest)
		return
	}
	// Simulate login logic
	_ = json.NewEncoder(w).Encode(LoginResponse{Token: "example-token"})
}

func GetUserHandler(w http.ResponseWriter, r *http.Request) {
	var req GetUserRequest
	vars := mux.Vars(r)
	id := vars["id"]
	if id == "" {
		http.Error(w, "User ID is required", http.StatusBadRequest)
		return
	}
	req.ID = id
	// Simulate fetching user by ID
	user := User{ID: req.ID, Name: "John Doe"}
	_ = json.NewEncoder(w).Encode(user)
}

Documentation Features

Built-in Endpoints

When you create a muxopenapi router, the following endpoints are automatically available:

  • /docs โ€” Interactive UI documentation
  • /docs/openapi.yaml โ€” Raw OpenAPI specification in YAML format

If you want to disable the built-in UI, you can do so by passing option.WithDisableDocs() when creating the router:

r := muxopenapi.NewRouter(mux,
    option.WithTitle("My API"),
    option.WithVersion("1.0.0"),
    option.WithDisableDocs(),
)
Supported Documentation UIs

Choose from multiple UI options, powered by oaswrap/spec-ui:

  • Stoplight Elements โ€” Modern, clean design (default)
  • Swagger UI โ€” Classic interface with try-it functionality
  • ReDoc โ€” Three-panel responsive layout
  • Scalar โ€” Beautiful and fast interface
  • RapiDoc โ€” Highly customizable
r := muxopenapi.NewRouter(mux,
	option.WithTitle("My API"),
	option.WithVersion("1.0.0"),
	option.WithScalar(), // Use Scalar as the documentation UI
)
Embed Mode (Local Assets)

By default, UI providers use CDN assets to keep binaries small.

To serve embedded assets (offline mode), use option.WithUIOption(...) with the provider emb package directly:

import (
    stoplightemb "github.com/oaswrap/spec-ui/stoplightemb"
)

// example:
option.WithUIOption(stoplightemb.WithUI())
Rich Schema Documentation

Use struct tags to generate detailed OpenAPI schemas. Note: These tags are used only for OpenAPI spec generation and documentation - they do not perform actual request validation.

type CreateProductRequest struct {
    Name        string   `json:"name" required:"true" minLength:"1" maxLength:"100"`
    Description string   `json:"description" maxLength:"500"`
    Price       float64  `json:"price" required:"true" minimum:"0" maximum:"999999.99"`
    Category    string   `json:"category" required:"true" enum:"electronics,books,clothing"`
    Tags        []string `json:"tags" maxItems:"10"`
    InStock     bool     `json:"in_stock" default:"true"`
}

Supported tags are implemented by oaswrap/spec directly. Common request tags include json, form, path, query, header, and cookie; common schema tags include description, format, default, example, enum, minimum, maximum, minLength, maxLength, minItems, maxItems, nullable, deprecated, readOnly, and writeOnly. See the root Reflection Tags section for the complete list.

Example

Check out the examples directory for more complete implementations and use cases.

Best Practices

  1. Organize with Tags โ€” Group related operations using option.Tags()
  2. Document Everything โ€” Use option.Summary() and option.Description() for all routes
  3. Define Error Responses โ€” Include common error responses (400, 401, 404, 500)
  4. Document Schema Constraints โ€” Use reflection tags to describe OpenAPI schema constraints; keep runtime validation in handlers or middleware
  5. Security First โ€” Define and apply appropriate security schemes
  6. Version Your API โ€” Use route groups for API versioning (/api/v1, /api/v2)

API Reference

Contributing

We welcome contributions! Please open issues and PRs at the main oaswrap/spec repository.

License

MIT

Documentation ยถ

Index ยถ

Constants ยถ

This section is empty.

Variables ยถ

This section is empty.

Functions ยถ

This section is empty.

Types ยถ

type Generator ยถ

type Generator interface {
	Router

	// GenerateSchema generates the OpenAPI schema for the router.
	GenerateSchema(formats ...string) ([]byte, error)

	// MarshalJSON marshals the schema to JSON.
	MarshalJSON() ([]byte, error)

	// MarshalYAML marshals the schema to YAML.
	MarshalYAML() ([]byte, error)

	// Validate validates the schema.
	Validate() error

	// ValidateReport validates the schema and returns all findings.
	ValidateReport() error

	// WriteSchemaTo writes the schema to a file.
	WriteSchemaTo(path string) error
}

Generator is an interface that defines methods for generating OpenAPI schemas.

func NewGenerator ยถ

func NewGenerator(mux *mux.Router, opts ...option.OpenAPIOption) Generator

NewGenerator creates a new OpenAPI router with the provided mux.Router instance and options.

It initializes the OpenAPI configuration and sets up the necessary routes for serving.

func NewRouter ยถ

func NewRouter(mux *mux.Router, opts ...option.OpenAPIOption) Generator

NewRouter creates a new OpenAPI router with the provided mux.Router instance and options.

It initializes the OpenAPI configuration and sets up the necessary routes for serving.

type Route ยถ

type Route interface {
	// GetError returns an error resulted from building the route, if any.
	GetError() error

	// GetHandler returns the handler for the route, if any.
	GetHandler() http.Handler

	// GetName returns the name for the route, if any.
	GetName() string

	// Handler sets a handler for the route.
	Handler(handler http.Handler) Route

	// HandlerFunc sets a handler function for the route.
	HandlerFunc(handler func(http.ResponseWriter, *http.Request)) Route

	// Headers adds a matcher for request header values. It accepts a sequence of key/value pairs to be matched.
	Headers(pairs ...string) Route

	// Host adds a matcher for the URL host. It accepts a template with zero or more URL variables enclosed by {}.
	Host(host string) Route

	// Methods adds a matcher for HTTP methods. It accepts a sequence of one or more methods to be matched, e.g.: "GET", "POST", "PUT".
	Methods(methods ...string) Route

	// Name sets the name for the route, used to build URLs. It is an error to call Name more than once on a route.
	Name(name string) Route

	// Path adds a matcher for the URL path. It accepts a template with zero or more URL variables enclosed by {}. The template must start with a "/".
	Path(path string) Route

	// PathPrefix adds a matcher for the URL path prefix. This matches if the given template is a prefix of the full URL path.
	PathPrefix(prefix string) Route

	// Queries adds a matcher for URL query values. It accepts a sequence of key/value pairs.
	Queries(pairs ...string) Route

	// Schemes adds a matcher for URL schemes. It accepts a sequence of schemes to be matched, e.g.: "http", "https".
	Schemes(schemes ...string) Route

	// SkipClean reports whether path cleaning is enabled for this route via Router.SkipClean.
	SkipClean() bool

	// Subrouter creates a subrouter for the route.
	Subrouter(opts ...option.GroupOption) Router

	// With applies OpenAPI operation options to this route.
	With(opts ...option.OperationOption) Route
}

Route defines the interface for a route that can handle HTTP requests.

type Router ยถ

type Router interface {
	http.Handler

	// Get returns a route registered with the given name.
	Get(name string) Route

	// GetRoute returns a route registered with the given name.
	GetRoute(name string) Route

	// Handle registers a new route with a matcher for the URL path. See Route.Path() and Route.Handler().
	Handle(path string, handler http.Handler) Route

	// HandleFunc registers a new route with a matcher for the URL path. See Route.Path() and Route.HandlerFunc().
	HandleFunc(path string, handler func(http.ResponseWriter, *http.Request)) Route

	// Headers registers a new route with a matcher for request header values. See Route.Headers().
	Headers(pairs ...string) Route

	// Host registers a new route with a matcher for the URL host. See Route.Host().
	Host(host string) Route

	// Methods registers a new route with a matcher for HTTP methods. See Route.Methods().
	Methods(methods ...string) Route

	// Name registers a new route with a name. See Route.Name().
	Name(name string) Route

	// NewRoute registers an empty route.
	NewRoute() Route

	// Path registers a new route with a matcher for the URL path. See Route.Path().
	Path(path string) Route

	// PathPrefix registers a new route with a matcher for the URL path prefix. See Route.PathPrefix().
	PathPrefix(prefix string) Route

	// Queries registers a new route with a matcher for URL query values. See Route.Queries().
	Queries(pairs ...string) Route

	// Schemes registers a new route with a matcher for URL schemes. See Route.Schemes().
	Schemes(schemes ...string) Route

	// SkipClean defines the path cleaning behaviour for new routes. The initial value is false.
	SkipClean(value bool) Router

	// StrictSlash defines the trailing slash behavior for new routes. The initial value is false.
	StrictSlash(value bool) Router

	// Use appends a MiddlewareFunc to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router.
	Use(middlewares ...mux.MiddlewareFunc) Router

	// UseEncodedPath tells the router to match the encoded original path to the routes.
	UseEncodedPath() Router

	// With applies OpenAPI group options to this router.
	With(opts ...option.GroupOption) Router
}

Router is an interface that defines methods for handling HTTP routes with OpenAPI support.

Jump to

Keyboard shortcuts

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