mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
76 lines
2.4 KiB
Go
76 lines
2.4 KiB
Go
package mvc
|
|
|
|
import (
|
|
"net/http"
|
|
"path"
|
|
|
|
"github.com/kataras/iris/v12/context"
|
|
)
|
|
|
|
// GRPC registers a controller which serves gRPC clients.
|
|
// It accepts the controller ptr to a struct value,
|
|
// the gRPCServer itself, and a strict option which is explained below.
|
|
//
|
|
// The differences between an GRPC-based controller and a common one are:
|
|
// HTTP verb: only POST (Party.AllowMethods can be used for more),
|
|
// method parsing is disabled: path is the function name as it is,
|
|
// if 'strictMode' option is true then this controller will only serve gRPC-based clients
|
|
// and fires 404 on common HTTP clients,
|
|
// otherwise HTTP clients can send and receive JSON (protos contain json struct fields by-default).
|
|
type GRPC struct {
|
|
// Server is required and should be gRPC Server derives from google's grpc package.
|
|
Server http.Handler
|
|
// ServiceName is required and should be the name of the service (used to build the gRPC route path),
|
|
// e.g. "helloworld.Greeter".
|
|
// For a controller's method of "SayHello" and ServiceName "helloworld.Greeter",
|
|
// both gRPC and common HTTP request path is: "/helloworld.Greeter/SayHello".
|
|
//
|
|
// Tip: the ServiceName can be fetched through proto's file descriptor, e.g.
|
|
// serviceName := pb.File_helloworld_proto.Services().Get(0).FullName().
|
|
ServiceName string
|
|
|
|
// When Strict option is true then this controller will only serve gRPC-based clients
|
|
// and fires 404 on common HTTP clients.
|
|
Strict bool
|
|
}
|
|
|
|
var _ Option = GRPC{}
|
|
|
|
// Apply parses the controller's methods and registers gRPC handlers to the application.
|
|
func (g GRPC) Apply(c *ControllerActivator) {
|
|
defer c.Activated()
|
|
|
|
pre := func(ctx *context.Context) {
|
|
if ctx.IsGRPC() { // gRPC, consumes and produces protobuf.
|
|
g.Server.ServeHTTP(ctx.ResponseWriter(), ctx.Request())
|
|
ctx.StopExecution()
|
|
return
|
|
}
|
|
|
|
// If strict was true fires 404 on common HTTP clients.
|
|
if g.Strict {
|
|
ctx.NotFound()
|
|
ctx.StopExecution()
|
|
return
|
|
}
|
|
|
|
// Allow common HTTP clients, consumes and produces JSON.
|
|
ctx.Next()
|
|
}
|
|
|
|
for i := 0; i < c.Type.NumMethod(); i++ {
|
|
m := c.Type.Method(i)
|
|
path := path.Join(g.ServiceName, m.Name)
|
|
if g.Strict {
|
|
c.app.Router.HandleMany(http.MethodPost, path, pre)
|
|
} else if route := c.Handle(http.MethodPost, path, m.Name, pre); route != nil {
|
|
bckp := route.Description
|
|
route.Description = "gRPC"
|
|
if g.Strict {
|
|
route.Description += "-only"
|
|
}
|
|
route.Description += " " + bckp // e.g. "gRPC controller"
|
|
}
|
|
}
|
|
}
|