api.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package api
  2. import (
  3. "context"
  4. "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger"
  5. "git.sxidc.com/go-tools/utils/strutils"
  6. "github.com/gin-gonic/gin"
  7. "github.com/pkg/errors"
  8. "net/http"
  9. "runtime/debug"
  10. "slices"
  11. "strconv"
  12. "time"
  13. )
  14. type Api struct {
  15. options Options
  16. server *http.Server
  17. rootRouter *RootRouter
  18. prefixRouter *PrefixRouter
  19. }
  20. func New(opts ...Option) *Api {
  21. options := new(Options)
  22. for _, opt := range opts {
  23. opt(options)
  24. }
  25. if strutils.IsStringEmpty(options.port) {
  26. options.port = "8080"
  27. }
  28. engine := gin.New()
  29. server := &http.Server{
  30. Addr: ":" + options.port,
  31. Handler: engine,
  32. }
  33. engine.Use(
  34. // 日志中间件
  35. func(c *gin.Context) {
  36. start := time.Now()
  37. c.Next()
  38. path := c.FullPath()
  39. if slices.Contains(options.logSkipPaths, path) {
  40. return
  41. }
  42. end := time.Now()
  43. logger.GetInstance().Info(" %d | %s | %s \"%s\"",
  44. c.Writer.Status(),
  45. strconv.Itoa(int(end.Sub(start).Milliseconds()))+"ms",
  46. c.Request.Method,
  47. path,
  48. )
  49. },
  50. // recover
  51. func(c *gin.Context) {
  52. err := recover()
  53. if err != nil {
  54. logger.GetInstance().Error("%s", debug.Stack())
  55. }
  56. })
  57. api := &Api{
  58. options: *options,
  59. server: server,
  60. rootRouter: newRootRouter(engine),
  61. }
  62. if strutils.IsStringNotEmpty(options.urlPrefix) {
  63. api.prefixRouter = newPrefixRouter(engine.Group(options.urlPrefix))
  64. }
  65. return api
  66. }
  67. func NewWithEngine(server *http.Server, engine *gin.Engine, opts ...Option) *Api {
  68. options := new(Options)
  69. for _, opt := range opts {
  70. opt(options)
  71. }
  72. if strutils.IsStringEmpty(options.port) {
  73. options.port = "8080"
  74. }
  75. api := &Api{
  76. options: *options,
  77. server: server,
  78. rootRouter: newRootRouter(engine),
  79. }
  80. if strutils.IsStringNotEmpty(options.urlPrefix) {
  81. api.prefixRouter = newPrefixRouter(engine.Group(options.urlPrefix))
  82. }
  83. return api
  84. }
  85. // Start 运行Api
  86. // 参数: 无
  87. // 返回值:
  88. // - 错误
  89. func (api *Api) Start() error {
  90. err := api.server.ListenAndServe()
  91. if err != nil && !errors.Is(err, http.ErrServerClosed) {
  92. return errors.New(err.Error())
  93. }
  94. return nil
  95. }
  96. // Finish 终止Api
  97. // 参数: 无
  98. // 返回值:
  99. // - 错误
  100. func (api *Api) Finish() error {
  101. err := api.server.Shutdown(context.Background())
  102. if err != nil {
  103. return errors.New(err.Error())
  104. }
  105. return nil
  106. }
  107. // Options 获取Api的选项
  108. // 参数: 无
  109. // 返回值:
  110. // - Api的选项
  111. func (api *Api) Options() Options {
  112. return api.options
  113. }
  114. // RootRouter 获取Api的根路由
  115. // 参数: 无
  116. // 返回值:
  117. // - Api的根路由
  118. func (api *Api) RootRouter() Router {
  119. return api.rootRouter
  120. }
  121. // PrefixRouter 获取Api的前缀路由
  122. // 参数: 无
  123. // 返回值:
  124. // - Api的前缀路由
  125. func (api *Api) PrefixRouter() Router {
  126. if api.prefixRouter == nil {
  127. return api.rootRouter
  128. }
  129. return api.prefixRouter
  130. }
  131. const (
  132. RouterRoot = "root"
  133. RouterPrefix = "prefix"
  134. )
  135. // ChooseRouter 选择Router
  136. // 参数:
  137. // - routerType: 路由类型,有两种
  138. // - api.RouterRoot: 根路由
  139. // - api.RouterPrefix: 带url前缀的路由
  140. //
  141. // - version: 版本,用于获取基于上面两中路由够造的带有版本号的路由,传空字符串则选定上面两种路由本身
  142. // 返回值:
  143. // - 选择的Router
  144. func (api *Api) ChooseRouter(routerType string, version string) Router {
  145. var router Router
  146. switch routerType {
  147. case RouterRoot:
  148. router = api.RootRouter()
  149. case RouterPrefix:
  150. router = api.PrefixRouter()
  151. default:
  152. router = api.PrefixRouter()
  153. }
  154. if strutils.IsStringNotEmpty(version) {
  155. router = router.VersionedRouter(version)
  156. }
  157. return router
  158. }