SkillAgentSearch skills...

Swag

No comments, simple go wrapper to create swagger 2.0 compatible APIs. Support most routing frameworks, such as built-in, gin, chi, mux, echo, httprouter, fasthttp and more.

Install / Use

npx skills add zc2638/swag

Installs into whichever agent you are using.

README

swag

LICENSE GoDoc GitHub Workflow Status Go Report Card codecov

English | 简体中文

swag is a lightweight library to generate swagger json for Golang projects.

swag is heavily geared towards generating REST/JSON apis.

No code generation, no framework constraints, just a simple swagger definition.

Dependency

Golang 1.16+

Installation

go get -u github.com/zc2638/swag@v1.5.1

Tip: As of v1.2.0, lower versions are no longer compatible. In order to be compatible with most web frameworks, the overall architecture has been greatly changed.

Default Swagger UI Server

func main() {
    handle := swag.UIHandler("/swagger/ui", "", false)
    patterns := swag.UIPatterns("/swagger/ui")
    for _, pattern := range patterns {
        http.DefaultServeMux.Handle(pattern, handle)
    }
    
    log.Fatal(http.ListenAndServe(":8080", nil))
}

so you can visit for UI: http://localhost:8080/swagger/ui

Examples

definition

package main

import (
	"fmt"
	"io"
	"net/http"

	"github.com/zc2638/swag"
	"github.com/zc2638/swag/endpoint"
	"github.com/zc2638/swag/option"
)

// Category example from the swagger pet store
type Category struct {
	ID     int64  `json:"category"`
	Name   string `json:"name" enum:"dog,cat" required:""`
	Exists *bool  `json:"exists" required:""`
}

// Pet example from the swagger pet store
type Pet struct {
	ID        int64     `json:"id"`
	Category  *Category `json:"category" desc:"分类"`
	Name      string    `json:"name" required:"" example:"张三" desc:"名称"`
	PhotoUrls []string  `json:"photoUrls"`
	Tags      []string  `json:"tags" desc:"标签"`
}

func handle(w http.ResponseWriter, r *http.Request) {
	_, _ = io.WriteString(w, fmt.Sprintf("[%s] Hello World!", r.Method))
}

func main() {
	api := swag.New(
		option.Title("Example API Doc"),
		option.Security("petstore_auth", "read:pets"),
		option.SecurityScheme("petstore_auth",
			option.OAuth2Security("accessCode", "http://example.com/oauth/authorize", "http://example.com/oauth/token"),
			option.OAuth2Scope("write:pets", "modify pets in your account"),
			option.OAuth2Scope("read:pets", "read your pets"),
		),
	)
	api.AddEndpoint(
		endpoint.New(
			http.MethodPost, "/pet",
			endpoint.Handler(handle),
			endpoint.Summary("Add a new pet to the store"),
			endpoint.Description("Additional information on adding a pet to the store"),
			endpoint.Body(Pet{}, "Pet object that needs to be added to the store", true),
			endpoint.Response(http.StatusOK, "Successfully added pet", endpoint.SchemaResponseOption(Pet{})),
			endpoint.Security("petstore_auth", "read:pets", "write:pets"),
		),
		endpoint.New(
			http.MethodGet, "/pet/{petId}",
			endpoint.Handler(handle),
			endpoint.Summary("Find pet by ID"),
			endpoint.Path("petId", "integer", "ID of pet to return", true),
			endpoint.Response(http.StatusOK, "successful operation", endpoint.SchemaResponseOption(Pet{})),
			endpoint.Security("petstore_auth", "read:pets"),
		),
		endpoint.New(
			http.MethodPut, "/pet/{petId}",
			endpoint.Handler(handle),
			endpoint.Path("petId", "integer", "ID of pet to return", true),
			endpoint.Security("petstore_auth", "read:pets"),
			endpoint.ResponseSuccess(endpoint.SchemaResponseOption(struct {
				ID   string `json:"id"`
				Name string `json:"name"`
			}{})),
		),
	)

	...
}

built-in

func main() {
    ...
    // Note: Built-in routes cannot automatically resolve path parameters.
    for p, endpoints := range api.Paths {
        http.DefaultServeMux.Handle(path.Join(api.BasePath, p), endpoints)
    }
    http.DefaultServeMux.Handle("/swagger/json", api.Handler())
    patterns := swag.UIPatterns("/swagger/ui")
    for _, pattern := range patterns {
        http.DefaultServeMux.Handle(pattern, swag.UIHandler("/swagger/ui", "/swagger/json", true))
    }
    
    log.Fatal(http.ListenAndServe(":8080", nil))
}

gin

func main() {
    ...
    
    router := gin.New()
    api.Walk(func (path string, e *swag.Endpoint) {
        h := e.Handler.(http.Handler)
        path = swag.ColonPath(path)
        
        router.Handle(e.Method, path, gin.WrapH(h))
    })
    
    // Register Swagger JSON route
    router.GET("/swagger/json", gin.WrapH(api.Handler()))
    
    // Register Swagger UI route
    // To take effect, the swagger json route must be registered
    router.GET("/swagger/ui/*any", gin.WrapH(swag.UIHandler("/swagger/ui", "/swagger/json", true)))
    
    log.Fatal(http.ListenAndServe(":8080", router))
}

chi

func main() {
    ...
    
    router := chi.NewRouter()
    api.Walk(func (path string, e *swag.Endpoint) {
        router.Method(e.Method, path, e.Handler.(http.Handler))
    })
    router.Handle("/swagger/json", api.Handler())
    router.Mount("/swagger/ui", swag.UIHandler("/swagger/ui", "/swagger/json", true))
    
    log.Fatal(http.ListenAndServe(":8080", router))
}

mux

func main() {
    ...
    
    router := mux.NewRouter()
    api.Walk(func (path string, e *swag.Endpoint) {
        h := e.Handler.(http.HandlerFunc)
        router.Path(path).Methods(e.Method).Handler(h)
    })
    
    router.Path("/swagger/json").Methods("GET").Handler(api.Handler())
    router.PathPrefix("/swagger/ui").Handler(swag.UIHandler("/swagger/ui", "/swagger/json", true))
    
    log.Fatal(http.ListenAndServe(":8080", router))
}

echo

func main() {
    ...
    
    router := echo.New()
    api.Walk(func (path string, e *swag.Endpoint) {
        h := echo.WrapHandler(e.Handler.(http.Handler))
        path = swag.ColonPath(path)
        
        switch strings.ToLower(e.Method) {
        case "get":
            router.GET(path, h)
        case "head":
            router.HEAD(path, h)
        case "options":
            router.OPTIONS(path, h)
        case "delete":
            router.DELETE(path, h)
        case "put":
            router.PUT(path, h)
        case "post":
            router.POST(path, h)
        case "trace":
            router.TRACE(path, h)
        case "patch":
            router.PATCH(path, h)
        case "connect":
            router.CONNECT(path, h)
        }
    })
    
    router.GET("/swagger/json", echo.WrapHandler(api.Handler()))
    router.GET("/swagger/ui/*", echo.WrapHandler(swag.UIHandler("/swagger/ui", "/swagger/json", true)))
    
    log.Fatal(http.ListenAndServe(":8080", router))
}

httprouter

func main() {
    ...
    
    router := httprouter.New()
    api.Walk(func (path string, e *swag.Endpoint) {
        h := e.Handler.(http.Handler)
        path = swag.ColonPath(path)
        router.Handler(e.Method, path, h)
    })
    
    router.Handler(http.MethodGet, "/swagger/json", api.Handler())
    router.Handler(http.MethodGet, "/swagger/ui/*any", swag.UIHandler("/swagger/ui", "/swagger/json", true))
    
    log.Fatal(http.ListenAndServe(":8080", router))
}

fasthttp

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"path"
	"path/filepath"
	"strings"

	"github.com/fasthttp/router"
	"github.com/valyala/fasthttp"

	"github.com/zc2638/swag"
	"github.com/zc2638/swag/asserts"
	"github.com/zc2638/swag/endpoint"
	"github.com/zc2638/swag/option"
)

// Category example from the swagger pet store
type Category struct {
	ID     int64  `json:"category"`
	Name   string `json:"name" enum:"dog,cat" required:""`
	Exists *bool  `json:"exists" required:""`
}

// Pet example from the swagger pet store
type Pet struct {
	ID        int64     `json:"id"`
	Category  *Category `json:"category" desc:"分类"`
	Name      string    `json:"name" required:"" example:"张三" desc:"名称"`
	PhotoUrls []string  `json:"photoUrls"`
	Tags      []string  `json:"tags" desc:"标签"`
}

func handle(ctx *fasthttp.RequestCtx) {
	str := fmt.Sprintf("[%s] Hello World!", string(ctx.Method()))
	_, _ = ctx.Write([]byte(str))
}

func main() {
	post := endpoint.New("post", "/pet", endpoint.Summary("Add a new pet to the store"),
		endpoint.Handler(handle),
		endpoint.Description("Additional information on adding a pet to the store"),
		endpoint.Body(Pet{}, "Pet object that needs to be added to the store", true),
		endpoint.Response(http.StatusOK, "Successfully added pet", endpoint.SchemaResponseOption(Pet{})),
		endpoint.Security("petstore_auth", "read:pets", "write:pets"),
	)
	get := endpoint.New("get", "/pet/{petId}", endpoint.Summary("Find pet by ID"),
		endpoint.Handler(handle),
		endpoint.Path("petId", "integer", "ID of pet to return", true),
		endpoint.Response(http.StatusOK, "successful operation", endpoint.SchemaResponseOption(Pet{})),
		endpoint.Security("petstore_auth", "read:pets"),
	)
	test := endpoint.New("put", "/pet/{petId}",
		endpoint.Handler(handle),
		endpoint.Path("petId", "integer", "ID of pet to return", true),
		endpoint.Response(http.StatusOK, "successful operation", endpoint.SchemaResponseOption(struct {
			ID   string `json:"id"`
			Name string `json:"name"`
		}{})),
		endpoint.Security("petstore_auth", "read:pets"),
	)

	api := swag.New(
		option.Title("Example API Doc"),
		option.Security("petstore_auth", "read:pets"),
		option.SecurityScheme("petstore_auth",
			option.OAuth2Security("accessCode", "http://example.com/oauth/authorize", "http://example.com/oauth/token"),
			option.OAuth2Scope("write:pets", "modify pets in your account"),
			option.OAuth2Scope("read:pets", "read your p

Related Skills

View on GitHub
GitHub Stars49
CategoryCustomer
Updated2mo ago
Forks7

Languages

Go

Security Score

95/100

Audited on May 23, 2026

No findings