httpopenapi

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: 9 Imported by: 0

README

httpopenapi

Go Reference Go Report Card

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

Features

  • ⚡ Seamless Integration — Works with your existing net/http 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/httpopenapi

Quick Start

package main

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

	"github.com/oaswrap/spec/adapter/httpopenapi"
	"github.com/oaswrap/spec/option"
)

func main() {
	mainMux := http.NewServeMux()
	r := httpopenapi.NewGenerator(mainMux,
		option.WithTitle("My API"),
		option.WithVersion("1.0.0"),
		option.WithSecurity("bearerAuth", option.SecurityHTTPBearer("Bearer")),
	)

	r.Route("/api/v1", func(r httpopenapi.Router) {
		r.HandleFunc("POST /login", LoginHandler).With(
			option.Summary("User login"),
			option.Request(new(LoginRequest)),
			option.Response(200, new(LoginResponse)),
		)
		auth := r.Group("/", AuthMiddleware).With(
			option.GroupSecurity("bearerAuth"),
		)
		auth.HandleFunc("GET /users/{id}", GetUserHandler).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:           mainMux,
		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
	id := r.PathValue("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 httpopenapi 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 := httpopenapi.NewGenerator(mainMux,
	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 := httpopenapi.NewGenerator(mainMux,
	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

	// Validate checks if the OpenAPI schema is valid.
	Validate() error

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

	// GenerateSchema generates the OpenAPI schema in the specified formats.
	// Supported formats include "yaml", "json", etc.
	// If no formats are specified, it defaults to "yaml".
	GenerateSchema(formats ...string) ([]byte, error)

	// MarshalYAML generates the OpenAPI schema in YAML format.
	MarshalYAML() ([]byte, error)

	// MarshalJSON generates the OpenAPI schema in JSON format.
	MarshalJSON() ([]byte, error)

	// WriteSchemaTo writes the OpenAPI schema to a file in the specified format.
	WriteSchemaTo(filename string) error
}

Generator is an interface for generating OpenAPI documentation for HTTP applications.

func NewGenerator

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

NewGenerator creates a new OpenAPI router with the specified http router and options.

It initializes the OpenAPI generator and sets up the necessary handlers for OpenAPI documentation.

func NewRouter

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

NewRouter creates a new OpenAPI router with the specified http router and options.

It initializes the OpenAPI generator and sets up the necessary handlers for OpenAPI documentation.

type Route

type Route interface {
	// With applies operation options to the route.
	With(opts ...option.OperationOption) Route
}

Route is an interface for defining a route with OpenAPI options.

type Router

type Router interface {
	http.Handler

	// HandleFunc registers a handler function for the specified pattern.
	HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) Route

	// Handle registers a handler for the specified pattern.
	Handle(pattern string, handler http.Handler) Route

	// Group creates a new sub-router with the specified options.
	Group(prefix string, middlewares ...func(http.Handler) http.Handler) Router

	// Route creates a new route with the specified pattern and handler function.
	Route(prefix string, fn func(r Router), middlewares ...func(http.Handler) http.Handler) Router

	// With applies group level options to the router.
	With(opts ...option.GroupOption) Router
}

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

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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