yao/service/service.go
Max 6e68efaba3 Implement gRPC support in the Yao SDK
- Add gRPC server configuration to the application, allowing for gRPC communication.
- Introduce new Makefile targets for gRPC unit testing and proto code generation.
- Update CI workflows to include gRPC tests with SQLite as the transport layer.
- Refactor the sandbox design to support multi-node capabilities and improve isolation.
- Enhance the service layer to facilitate internal request forwarding for gRPC APIs.

This commit lays the groundwork for integrating gRPC into the Yao SDK, improving performance and scalability.
2026-03-04 13:17:48 +08:00

121 lines
2.4 KiB
Go

package service
import (
"time"
"github.com/gin-gonic/gin"
"github.com/yaoapp/gou/api"
"github.com/yaoapp/gou/server/http"
"github.com/yaoapp/yao/config"
"github.com/yaoapp/yao/openapi"
"github.com/yaoapp/yao/share"
)
// Router holds the active gin.Engine so the gRPC API proxy can forward
// requests internally without an HTTP round-trip.
var Router *gin.Engine
// Start the yao service
func Start(cfg config.Config) (*http.Server, error) {
if cfg.AllowFrom == nil {
cfg.AllowFrom = []string{}
}
err := prepare()
if err != nil {
return nil, err
}
router := gin.New()
Router = router
router.Use(Middlewares...)
var apiRoot string
if openapi.Server != nil {
// OpenAPI mode: use OAuth guards and dynamic routing
apiRoot = openapi.Server.Config.BaseURL
api.SetGuards(OpenAPIGuards())
// Developer APIs: use dynamic proxy (supports hot-reload)
router.Any(apiRoot+"/api/*path", DynamicAPIHandler)
// Widgets and system APIs: static registration
api.SetRoutes(router, apiRoot, cfg.AllowFrom...)
// Build route table for dynamic lookup
api.BuildRouteTable()
// Attach OpenAPI built-in features
openapi.Server.Attach(router)
} else {
// Traditional mode: unchanged
apiRoot = "/api"
api.SetGuards(Guards)
api.SetRoutes(router, "/api", cfg.AllowFrom...)
}
srv := http.New(router, http.Option{
Host: cfg.Host,
Port: cfg.Port,
Root: apiRoot,
Allows: cfg.AllowFrom,
Timeout: 5 * time.Second,
})
go func() {
err = srv.Start()
}()
return srv, nil
}
// Restart the yao service
func Restart(srv *http.Server, cfg config.Config) error {
router := gin.New()
Router = router
router.Use(Middlewares...)
if openapi.Server != nil {
// OpenAPI mode
baseURL := openapi.Server.Config.BaseURL
api.SetGuards(OpenAPIGuards())
router.Any(baseURL+"/api/*path", DynamicAPIHandler)
api.SetRoutes(router, baseURL, cfg.AllowFrom...)
api.BuildRouteTable()
openapi.Server.Attach(router)
} else {
// Traditional mode: unchanged
api.SetGuards(Guards)
api.SetRoutes(router, "/api", cfg.AllowFrom...)
}
srv.Reset(router)
return srv.Restart()
}
// Stop the yao service
func Stop(srv *http.Server) error {
err := srv.Stop()
if err != nil {
return err
}
<-srv.Event()
return nil
}
func prepare() error {
// Session server
err := share.SessionStart()
if err != nil {
return err
}
err = SetupStatic()
if err != nil {
return err
}
return nil
}