Files
crawlab/core/apps/api.go
Marvin Zhang d6badb533d feat: enhance API routing and OpenAPI documentation support
- Introduced a new OpenAPI wrapper using Fizz for improved API documentation
- Refactored base controller to support more flexible route handling
- Added dynamic route registration with OpenAPI metadata
- Implemented generic response types for consistent API responses
- Updated router initialization to support OpenAPI documentation endpoint
- Improved route and resource naming utilities
- Migrated existing controllers to use new routing and response mechanisms
2025-03-11 23:45:06 +08:00

124 lines
2.2 KiB
Go

package apps
import (
"context"
"errors"
"github.com/crawlab-team/crawlab/core/controllers"
"github.com/crawlab-team/crawlab/core/interfaces"
"github.com/crawlab-team/crawlab/core/middlewares"
"github.com/crawlab-team/crawlab/core/utils"
"github.com/gin-gonic/gin"
"net"
"net/http"
"sync"
"time"
)
func init() {
// set gin mode
gin.SetMode(utils.GetGinMode())
}
type Api struct {
// internals
app *gin.Engine
ln net.Listener
srv *http.Server
initialized bool
interfaces.Logger
}
func (app *Api) Init() {
// skip if already initialized
if app.initialized {
return
}
// initialize middlewares
_ = app.initModuleWithApp("middlewares", middlewares.InitMiddlewares)
// initialize routes
_ = app.initModuleWithApp("routes", controllers.InitRoutes)
// set initialized
app.initialized = true
}
func (app *Api) Start() {
// address
address := utils.GetServerAddress()
// http server
app.srv = &http.Server{
Handler: app.GetHttpServerHandler(),
Addr: address,
}
// listen
var err error
app.ln, err = net.Listen("tcp", address)
if err != nil {
panic(err)
}
app.Infof("api server listening on %s", address)
// serve
if err := http.Serve(app.ln, app.app); err != nil {
if !errors.Is(err, http.ErrServerClosed) {
app.Errorf("run api server error: %v", err)
} else {
app.Info("api server graceful down")
}
}
}
func (app *Api) Wait() {
utils.DefaultWait()
}
func (app *Api) Stop() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := app.srv.Shutdown(ctx); err != nil {
app.Errorf("shutdown api server error: %v", err)
}
}
func (app *Api) GetHttpServerHandler() http.Handler {
return controllers.GetGlobalFizzWrapper().GetFizz()
}
func (app *Api) GetGinEngine() *gin.Engine {
return app.app
}
func (app *Api) GetHttpServer() *http.Server {
return app.srv
}
func (app *Api) initModuleWithApp(name string, fn func(app *gin.Engine) error) (err error) {
return initModule(name, func() error {
return fn(app.app)
})
}
func newApi() *Api {
api := &Api{
app: gin.New(),
Logger: utils.NewLogger("Api"),
}
api.Init()
return api
}
var api *Api
var apiOnce sync.Once
func GetApi() *Api {
apiOnce.Do(func() {
api = newApi()
})
return api
}