Grpc
Introduction
Grpc module can be operated by facades.Grpc()
.
Configuration
In the config/grpc.go
file, you can configure the Grpc module, where grpc.host
configures the domain name of the server, and grpc.clients
configures the relevant information of the client.
Controllers
Controllers can be defined in the /app/grpc/controllers
directory.
// app/grpc/controllers
package controllers
import (
"context"
"net/http"
"github.com/goravel/grpc/protos"
)
type UserController struct {
}
func NewUserController() *UserController {
return &UserController{}
}
func (r *UserController) Show(ctx context.Context, req *protos.UserRequest) (protoBook *protos.UserResponse, err error) {
return &protos.UserResponse{
Code: http.StatusOK,
}, nil
}
Define routing
All routing files can be defined in the /routes
directory, such as /routes/grpc.go
. Then bind routes in the app/providers/grpc_service_provider.go
file.
// routes/grpc.go
package routes
import (
"github.com/goravel/grpc/protos"
"github.com/goravel/framework/facades"
"goravel/app/grpc/controllers"
)
func Grpc() {
protos.RegisterUserServer(facades.Grpc().Server(), controllers.NewUserController())
}
Register routing
Register routing in the app/providers/grpc_service_provider.go
file after routing was defined.
// app/providers/grpc_service_provider.go
package providers
import (
"goravel/routes"
)
type GrpcServiceProvider struct {
}
func (router *GrpcServiceProvider) Register() {
}
func (router *GrpcServiceProvider) Boot() {
routes.Grpc()
}
Start Grpc Server
Start Grpc in the main.go
file.
go func() {
if err := facades.Grpc().Run(facades.Config().GetString("grpc.host")); err != nil {
facades.Log().Errorf("Grpc run error: %v", err)
}
}()
Interceptor
The interceptor can be defined in the app/grpc/inteceptors
folder, and then registered to app/grpc/kernel.go
.
Server Interceptor
You can set the server interceptors in the app/grpc/kernel.go:UnaryServerInterceptors
method. For example:
// app/grpc/kernel.go
import (
"goravel/app/grpc/interceptors"
"google.golang.org/grpc"
)
func (kernel *Kernel) UnaryServerInterceptors() []grpc.UnaryServerInterceptor {
return []grpc.UnaryServerInterceptor{
interceptors.Server,
}
}
Client Interceptor
You can set the client interceptor in the app/grpc/kernel.go:UnaryClientInterceptorGroups
method, the method can group interceptors. For example, interceptors.Client
is included under the trace
group.
// app/grpc/kernel.go
import (
"goravel/app/grpc/interceptors"
"google.golang.org/grpc"
)
func (kernel *Kernel) UnaryClientInterceptorGroups() map[string][]grpc.UnaryClientInterceptor {
return map[string][]grpc.UnaryClientInterceptor{
"trace": {
interceptors.Client,
},
}
}
the trace
group can be applied to the configuration item grpc.clients.interceptors
, in this way, the Client will be applied to all interceptors under the group. For example:
package config
import (
"github.com/goravel/framework/facades"
)
func init() {
config := facades.Config
config.Add("grpc", map[string]interface{}{
// Grpc Configuration
//
// Configure your server host
"host": config.Env("GRPC_HOST", ""),
// Configure your client host and interceptors.
// Interceptors can be the group name of UnaryClientInterceptorGroups in app/grpc/kernel.go.
"clients": map[string]any{
"user": map[string]any{
"host": config.Env("GRPC_USER_HOST", ""),
"port": config.Env("GRPC_USER_PORT", ""),
"interceptors": []string{"trace"},
},
},
})
}
Shutdown Grpc
You can call the Shutdown
method to gracefully shut down Grpc, which will wait for all requests to be processed before shutting down.
// main.go
bootstrap.Boot()
// Create a channel to listen for OS signals
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
// Start schedule by facades.Schedule
go func() {
if err := facades.Grpc().Run(facades.Config().GetString("grpc.host")); err != nil {
facades.Log().Errorf("Grpc run error: %v", err)
}
}()
// Listen for the OS signal
go func() {
<-quit
if err := facades.Grpc().Shutdown(); err != nil {
facades.Log().Errorf("Grpc Shutdown error: %v", err)
}
os.Exit(0)
}()
select {}