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)
}

我的排序效果

相关推荐
0x派大星2 天前
【Golang】——Gin 框架中的 API 请求处理与 JSON 数据绑定
开发语言·后端·golang·go·json·gin
get2002 天前
Gin 框架中间件详细介绍
中间件·gin
bigbig猩猩2 天前
Gin 框架中的表单处理与数据绑定
驱动开发·gin
荣~博客3 天前
Golang语言整合jwt+gin框架实现token
开发语言·golang·gin
拧螺丝专业户3 天前
gin源码阅读(2)请求体中的JSON参数是如何解析的?
前端·json·gin
留乘船3 天前
使用gin -gorm-jwt-中间件拦截的一个小项目
开发语言·学习·中间件·golang·gin
0x派大星5 天前
【Golang】——Gin 框架中的模板渲染详解
开发语言·后端·golang·go·gin
0x派大星5 天前
【Golang】——Gin 框架中的表单处理与数据绑定
开发语言·后端·golang·go·gin
杜杜的man5 天前
【go从零单排】gin+gorm理解及实现CRUD
开发语言·golang·gin
杨若瑜6 天前
Go语言24小时极速学习教程(五)Go语言中的SpringMVC框架——Gin
学习·golang·gin