github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/server/api_version.go (about)

     1  package server
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/gin-gonic/gin"
     7  	"github.com/isyscore/isc-gobase/isc"
     8  	. "github.com/isyscore/isc-gobase/isc"
     9  )
    10  
    11  type ApiPath struct {
    12  	Path     string
    13  	Handler  gin.HandlerFunc
    14  	Method   HttpMethod
    15  	Versions ISCList[*ApiVersion]
    16  }
    17  
    18  type ApiVersion struct {
    19  	Header  []string
    20  	Version []string
    21  	Handler gin.HandlerFunc
    22  }
    23  
    24  var apiVersionList ISCList[*ApiPath]
    25  
    26  func GetApiPath(path string, method HttpMethod) *ApiPath {
    27  	v := apiVersionList.Find(func(ap *ApiPath) bool {
    28  		return ap.Path == path && ap.Method == method
    29  	})
    30  	if v == nil {
    31  		return nil
    32  	} else {
    33  		return *v
    34  	}
    35  }
    36  
    37  func NewApiPath(path string, method HttpMethod) *ApiPath {
    38  	v := ApiPath{
    39  		Path:   path,
    40  		Method: method,
    41  	}
    42  	v.Handler = func(c *gin.Context) {
    43  		v.Versions.ForEach(func(a *ApiVersion) {
    44  			// 取出所有已定义header所对应的值
    45  			t := isc.ListToMapFrom[string, string](a.Header).Map(func(item string) string {
    46  				return c.GetHeader(item)
    47  			})
    48  			if isc.ListEquals(a.Version, t) {
    49  				// 找到符合条件的路由版本,并转发请求
    50  				a.Handler(c)
    51  			}
    52  		})
    53  	}
    54  	// 将路由添加到维护列表中,只有第一次添加时,会注册到gin
    55  	apiVersionList = append(apiVersionList, &v)
    56  	return &v
    57  }
    58  
    59  func (ap *ApiPath) AddVersion(header []string, version []string, handler gin.HandlerFunc) {
    60  	// 查找指定版本的路由是否已经存在
    61  	av := ap.Versions.Find(func(a *ApiVersion) bool {
    62  		return isc.ListEquals(a.Header, header) && isc.ListEquals(a.Version, version)
    63  	})
    64  	if av == nil {
    65  		// 不存在,则添加一个
    66  		a := &ApiVersion{Header: header, Version: version, Handler: handler}
    67  		ap.Versions = append(ap.Versions, a)
    68  	} else {
    69  		// 不允许重复添加
    70  		panic(fmt.Sprintf("版本 %s-%s 已经存在", header, version))
    71  	}
    72  }