Files
crawlab/core/openapi/wrapper.go
Marvin Zhang 4dace3ce8e refactor: migrate router and controller methods to use Fizz package
- Updated router groups to utilize the new crawlab-team/fizz package for improved routing capabilities.
- Refactored controller methods to accept Fizz router groups, enhancing consistency and maintainability.
- Simplified route registration by incorporating OpenAPI metadata directly into group definitions.
- Improved error handling and response generation in sync controller methods for better clarity.
- Enhanced overall code structure by standardizing route definitions and improving parameter handling.
2025-03-17 12:50:50 +08:00

130 lines
3.3 KiB
Go

package openapi
import (
"fmt"
"sync"
"github.com/crawlab-team/crawlab/core/interfaces"
"github.com/crawlab-team/crawlab/core/utils"
"github.com/crawlab-team/fizz"
"github.com/gin-gonic/gin"
"github.com/loopfz/gadgeto/tonic"
)
// FizzWrapper wraps an existing Gin Engine to add OpenAPI functionality
type FizzWrapper struct {
fizz *fizz.Fizz
gin *gin.Engine
logger interfaces.Logger
}
// newFizzWrapper creates a new wrapper around an existing Gin Engine
// This approach ensures we don't break existing functionality
func newFizzWrapper(engine *gin.Engine) *FizzWrapper {
// Create a new Fizz instance using the existing Gin engine
f := fizz.NewFromEngine(engine)
return &FizzWrapper{
fizz: f,
gin: engine,
logger: utils.NewLogger("FizzWrapper"),
}
}
// GetFizz returns the underlying Fizz instance
func (w *FizzWrapper) GetFizz() *fizz.Fizz {
return w.fizz
}
// GetGin returns the underlying Gin engine
func (w *FizzWrapper) GetGin() *gin.Engine {
return w.gin
}
// Response represents an OpenAPI response
type Response struct {
Description string
Model interface{}
}
// RegisterRoute registers a route with OpenAPI documentation
func (w *FizzWrapper) RegisterRoute(method, path string, group *fizz.RouterGroup, handler interface{}, id, summary, description string, responses map[int]Response) {
// Build operation options for OpenAPI documentation
opts := w.buildOperationOptions(id, summary, description, responses)
// Register the route with OpenAPI documentation
switch method {
case "GET":
group.GET(path, opts, tonic.Handler(handler, 200))
case "POST":
group.POST(path, opts, tonic.Handler(handler, 200))
case "PUT":
group.PUT(path, opts, tonic.Handler(handler, 200))
case "DELETE":
group.DELETE(path, opts, tonic.Handler(handler, 200))
case "PATCH":
group.PATCH(path, opts, tonic.Handler(handler, 200))
case "HEAD":
group.HEAD(path, opts, tonic.Handler(handler, 200))
case "OPTIONS":
group.OPTIONS(path, opts, tonic.Handler(handler, 200))
}
}
// BuildModelResponse builds a standard response model with a specific data type
func (w *FizzWrapper) BuildModelResponse() map[int]Response {
return map[int]Response{
400: {
Description: "Bad Request",
},
401: {
Description: "Unauthorized",
},
500: {
Description: "Internal Server Error",
},
}
}
// buildOperationOptions builds the options for a Fizz operation
func (w *FizzWrapper) buildOperationOptions(id, summary, description string, responses map[int]Response) []fizz.OperationOption {
var opts []fizz.OperationOption
// Add ID
if id != "" {
opts = append(opts, fizz.ID(id))
}
// Add summary
if summary != "" {
opts = append(opts, fizz.Summary(summary))
}
// Add description
if description != "" {
opts = append(opts, fizz.Description(description))
}
// Add responses
if responses != nil {
for status, response := range responses {
if response.Model != nil {
opts = append(opts, fizz.Response(fmt.Sprintf("%d", status), response.Description, response.Model, nil, nil))
} else {
opts = append(opts, fizz.Response(fmt.Sprintf("%d", status), response.Description, nil, nil, nil))
}
}
}
return opts
}
var wrapper *FizzWrapper
var wrapperOnce sync.Once
func GetFizzWrapper(app *gin.Engine) *FizzWrapper {
wrapperOnce.Do(func() {
wrapper = newFizzWrapper(app)
})
return wrapper
}