swagger gin 文档接口排序,写了一个小工具,自定义接口排序

起因没找到swagger 自定义接口排序

代码原理就是替换 swag init 生成的docs.go paths 部分 ,取到swagger.json paths 部分排序,正则匹配docs.go paths 部分,然后通过自定义排序,替换paths部分,这个根据自定义的需求来

代码如下

go 复制代码
package main

import (
	"encoding/json"
	"fmt"
	"github.com/tidwall/gjson"
	orderedmap "github.com/wk8/go-ordered-map/v2"
	"log"
	"os"
	"regexp"
	"sort"
	"strconv"
	"strings"
)

// GOOS=darwin GOARCH=arm64 go build -x -v -ldflags "-s -w" -o swagger_sort main.go
type Endpoint struct {
	Post struct {
		Security    []map[string][]interface{} `json:"security"`
		Description string                     `json:"description"`
		Consumes    []string                   `json:"consumes"`
		Produces    []string                   `json:"produces"`
		Tags        []string                   `json:"tags"`
		Summary     string                     `json:"summary"`
		Parameters  []map[string]interface{}   `json:"parameters"`
		Responses   map[string]interface{}     `json:"responses"`
	} `json:"post"`
}

func main() {
	goPath := os.Args[1]
	swaggerPath := os.Args[2]
	if goPath == "" || swaggerPath == "" {
		log.Fatal("文件不存在")
		return
	}

	// 从doc.go中读取内容
	content, err := os.ReadFile(goPath)
	if err != nil {
		log.Fatalf("Error reading docs.go: %v", err)
	}

	newPathsContent := getNewContents(swaggerPath)
	// 正则匹配 "paths" 及其后面的 {} 内容,但保留 "definitions"
	r := regexp.MustCompile(`(?s)"paths": (\{.*?\}),\s*"definitions"`)
	matches := r.FindStringSubmatch(string(content))
	if matches == nil {
		fmt.Println("No match found!")
		return
	}
	//fmt.Println("Matched:", matches[1])


	// Replace matched content in docs.go with newPathsContent
	updatedContent := string(content)
	updatedContent = strings.Replace(updatedContent, matches[1], newPathsContent, 1)

	// Write the updated content back to docs.go
	err = os.WriteFile(goPath, []byte(updatedContent), 0644)
	if err != nil {
		log.Fatalf("Error writing to docs.go: %v", err)
	}

	fmt.Println("Successfully wrote to test.js and updated docs.go!")
}

func extractNumberFromSummary(summary string) int {
	parts := strings.Split(summary, ".")
	if len(parts) > 0 {
		num, err := strconv.Atoi(parts[0])
		if err == nil {
			return num
		}
	}
	return 0
}

func getNewContents(swaggerPath string) string {
	content, err := os.ReadFile(swaggerPath)

	if err != nil {
		log.Fatalf("Error reading swagger.json: %v", err)
	}
	str := gjson.Get(string(content), "paths").String()

	var data map[string]Endpoint
	if err := json.Unmarshal([]byte(str), &data); err != nil {
		panic(err)
	}

	type PathItem struct {
		Path string
		Ep   Endpoint
	}

	var paths []PathItem
	for k, v := range data {
		paths = append(paths, PathItem{k, v})
	}

	sort.Slice(paths, func(i, j int) bool {
		if len(paths[i].Ep.Post.Tags) > 0 {
			if paths[i].Ep.Post.Tags[0] == paths[j].Ep.Post.Tags[0] {
				numI := extractNumberFromSummary(paths[i].Ep.Post.Summary)
				numJ := extractNumberFromSummary(paths[j].Ep.Post.Summary)
				return numI < numJ
			} else if strings.Contains(paths[i].Ep.Post.Tags[0], "测试") {
				return false
			} else {
				return true
			}
		}
		return true

	})

	//bytePath, _ := json.MarshalIndent(paths, "", "    ")
	//fmt.Println(string(bytePath))

	// 创建一个新的 ordered map
	orderedData := orderedmap.New[string, Endpoint]()

	// 从排序后的切片中填充 ordered map
	for _, item := range paths {
		orderedData.Set(item.Path, item.Ep)
	}

	// 编码 ordered map
	sortedJSON, err := json.MarshalIndent(orderedData, "", "    ")
	if err != nil {
		panic(err)
	}

	fmt.Println(string(sortedJSON))
	return string(sortedJSON)
}

我的排序效果

相关推荐
onlywhz2 天前
【Golang】——Gin 框架中间件详解:从基础到实战
中间件·golang·gin
不会写DN2 天前
Gin 接收前端传参方式有几种?
开发语言·前端·gin
I'm Jie5 天前
Swagger UI 本地化部署,解决 FastAPI Swagger UI 依赖外部 CDN 加载失败问题
python·ui·fastapi·swagger·swagger ui
贺小涛6 天前
Golang Gin框架核心原理与架构解析
架构·golang·gin
Murphy20238 天前
.net8 Swashbuckle.AspNetCore WEBAPI 配置要点记录
.net·swagger·webapi·swashbuckle
yashuk14 天前
Go-Gin Web 框架完整教程
前端·golang·gin
ErizJ14 天前
面试 | gin gorm go-zero
面试·golang·gin·gorm·gozero
透过清晨16 天前
Gin 框架中的规范响应格式设计与实现 (一)
gin
透过清晨16 天前
Gin 框架中的规范响应格式设计与实现 (五)
gin
透过清晨16 天前
Gin 框架中的规范响应格式设计与实现(二)
gin