123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- 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"
- }
- }
- }
|